(Özyineleme olmadan) bireysel basamak toplamına göre sıralı n basamaklı sayılar üreten

4 Cevap java

I sekansı tek basamak toplamı ile belirlenir aşağıdaki sırayla, içerisinde, n-haneli sayı bütün olası değerleri üretmek için ideal var.

Örneğin ile n = 3,

111     sum = 3
112     sum = 4
121
211
122     sum = 5
212
221
113
131
311
114     sum = 6
141
411
:::
999     sum = 27

Toplam grup içindeki sırası önemli değildir.

Herhangi bir yardım, fikir mutluluk duyacağız

4 Cevap

Önemli verilerin kendi yığınını korumak eğer always tekrarlanan bir birine bir özyinelemeli sorunu açabilirsiniz - özyineleme önlemek için neden dil bunu desteklemiyor ise budur.

Dil does bunu desteklemek Ama, eğer, o zaman recursive çözümleri çok daha zariftir.

Ben Özyinelemeyi kaçınmak için düşünebilirsiniz yalnızca diğer nedeni sınırlı yığını derinliğidir. Bu durumda bir özyinelemeli çözümün bir iteratif dönüşüm kadar yığın alanı gerekmeyen sorunu azaltmak olacaktır.

Ama işleme n numaralar için yığın derinliği sadece 10 log n göreli büyür anlamak gerekir. Diğer bir deyişle, sadece rakam (sadece 10 yığın kare 32-bit tamsayı dizi işlemek için) başına ekstra bir yığın çerçevesi olsun.

Aside: O noktaya ulaşmak zaman, sen algoritma çalıştırmak için uzun süre alacak konum, yığın kare :-) sorunların en az olacaktır

Burada bir özyinelemeli Python çözüm:

def recur (numdigits,sum,pref="",prefsum=0):
    if numdigits == 0:
        if prefsum == sum:
            print "%s, sum=%d"%(pref,prefsum)
    else:
        for i in range (1,10):
            recur (numdigits-1,sum,"%s%d"%(pref,i),prefsum+i)

def do (n):
    for i in range (1,n*9+1):
        recur (n,i)

do (2)
do (3)

hangi çıkışları (2 ve 3):

11, sum=2          111, sum=3
12, sum=3          112, sum=4
21, sum=3          121, sum=4
13, sum=4          211, sum=4
22, sum=4          113, sum=5
31, sum=4          122, sum=5
14, sum=5          131, sum=5
23, sum=5          212, sum=5
32, sum=5          221, sum=5
41, sum=5          311, sum=5
15, sum=6          114, sum=6
 :    :             :     :
89, sum=17         989, sum=26
98, sum=17         998, sum=26
99, sum=18         999, sum=27

Çözüm hala biraz optimize edilebilecek unutmayın - Ben zarif yineleme olabilir nasıl göstermek için başlangıç ​​formunda bıraktı. Saf-iteratif çözüm izler, ama ben yine özyinelemeli bir tercih.

Aşağıdaki programı çalıştırın ve istenilen sipariş almak için UNIX altında sort ve awk kullanın. Örneğin:

go | sort | awk '{print $2}'

Bu sıralama yapmak için harici araçlar kullanır ama olabilir gibi kolayca sıralamak C kodundaki (bellek izin) olduğunu unutmayın.

#include <stdio.h>

int main (void) {
    int i, sum, carry, size;
    int *pDigit;

    // Choose your desired size.

    size = 2;

    // Allocate and initialise digits.

    if ((pDigit = malloc (size * sizeof (int))) == NULL) {
        fprintf (stderr, "No memory\n");
        return 1;
    )

    for (i = 0; i < size; i++)
        pDigit[i] = 1;

    // Loop until overflow.

    carry = 0;
    while (carry != 1) {
        // Work out sum, then output it with number.
        // Line is sssssssssssssssssss ddddd
        //   where sss...sss is the fixed-width sum, zero padded on left (for sort)
        //   and ddd...ddd is the actual number.

        sum = 0;
        for (i = 0; i < size; i++)
            sum += pDigit[i];

        printf ("%020d ", sum);
        for (i = 0; i < size; i++)
            printf ("%d", pDigit[i]);
        printf ("\n");

        // Advance to next number.

        carry = 1;
        for (i = 0; i < size; i++) {
            pDigit[size-i-1] = pDigit[size-i-1] + carry;
            if (pDigit[size-i-1] == 10)
                pDigit[size-i-1] = 1;
            else
                carry = 0;
        }
    }

    return 0;
}

Kullanabilirsiniz std::next_permutation?

The next_permutation() function attempts to transform the given range of elements [start,end) into the next lexicographically greater permutation of elements. If it succeeds, it returns true, otherwise, it returns false.

If a strict weak ordering function object cmp is provided, it is used in lieu of the < operator when comparing elements.

Bu bakınız: previous SO answer

Bu kadar uzun bir desen (o aklınızda belirli bir modeline sahip olmadığını yazılan tamamen net değil), daha sonra n = 3 için, 111 ile başlar ve orada olduğu gibi kullanmak ne desen farketmez eğer artım ulaşana kadar 999.

Bu arada, sizin için soruyorsun ne için terim tam olarak "permütasyon" değildir.

Siz iki kova için sorunu azaltmak için deneyebilirsiniz:

İki kova böler basit: A yalnızca birini içeren kadar sonra B içine bir birini koymak, tüm eksi kepçe A one ve kova B biri ile başlayın.

Üç kova böler sonra sadece: tüm eksi kepçe A'da iki ve birer B ve C birer A azaltın ve B ve C üç bütün iki kepçe böler toplamak, sadece A birini içeren kadar tekrarlayın ile başlayın.