C# 算法:里程表/蛮力

C# 算法:里程表/蛮力,c#,algorithm,C#,Algorithm,我想用C风格的语言编写一个类似里程表的方法,但不只是对字符使用0-9,而是任何字符集。它或多或少会像一个暴力应用程序 如果我传入从0到J的字符数组,并将长度设置为5,我希望得到像00000、00001、00002这样的结果。。。HJJJJ,IJJJJJ,JJJJJJ 这是基础,请帮助我扩展: protected void Main() { char[] chars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9

我想用C风格的语言编写一个类似里程表的方法,但不只是对字符使用0-9,而是任何字符集。它或多或少会像一个暴力应用程序

如果我传入从0J的字符数组,并将长度设置为5,我希望得到像00000、00001、00002这样的结果。。。HJJJJ,IJJJJJ,JJJJJJ

这是基础,请帮助我扩展:

protected void Main()
{
    char[] chars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };

    BruteForce(chars, 5);
}

private void BruteForce(char[] chars, int length)
{
    // for-loop (?) console-writing all possible combinations from 00000 to JJJJJ
    // (when passed in length is 5)
    // TODO: Implement code...
}

谷歌搜索排列

但是,如果您只是处理该“十六进制”范围,只需执行以下操作:

for (int i = 0; i < (1 << 24); i++)
  string s = i.ToString("X6");
for(int i=0;i<(1这不是的完全重复,但非常接近。如果这对您没有帮助,我将编写一个解决方案

编辑:这是一个非递归的解决方案。递归的解决方案要从中返回
IEnumerable
稍微困难一些,但是返回迭代器会提供一个很好的接口(IMO:)

私有静态IEnumerable GetAllMatches(char[]chars,int-length)
{
int[]索引=新的int[长度];
字符[]当前=新字符[长度];
for(int i=0;i=0)
{
索引[位置]+;
if(索引[位置]<字符长度)
{
当前[位置]=字符[索引[位置];
返回true;
}
索引[位置]=0;
当前[位置]=字符[0];
位置--;
}
返回false;
}

以下是我以前使用过的一个类,用于此目的…顾名思义,它根据提供的字符集中的字符数以不同的基数计算。希望它有用

public class BaseNCounter
{
    public char[] CharSet { get; set; }
    public int Power { get; set; }

    public BaseNCounter() { }

    public IEnumerable<string> Count() {
        long max = (long)Math.Pow((double)this.CharSet.Length, (double)this.Power);
        long[] counts = new long[this.Power];
        for(long i = 0; i < max; i++)
            yield return IncrementArray(ref counts, i);
    }

    public string IncrementArray(ref long[] counts, long count) {
        long temp = count;
        for (int i = this.Power - 1; i >= 0 ; i--) {
            long pow = (long)Math.Pow(this.CharSet.Length, i);
            counts[i] = temp / pow;
            temp = temp % pow;
        }

        StringBuilder sb = new StringBuilder();
        foreach (int c in counts) sb.Insert(0, this.CharSet[c]);
        return sb.ToString();
    }
}

这是我找到的解决方案之一。我喜欢它的紧凑性和分离性:

private static char[] characters =
    new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };

// length: The length of the string created by bruteforce
public static void PerformBruteForce(int length) {
    int charactersLength = characters.Length;
    int[] odometer = new int[length];
    long size = (long)Math.Pow(charactersLength, length);

    for (int i = 0; i < size; i++) {
        WriteBruteForce(odometer, characters);
        int position = 0;
        do {
            odometer[position] += 1;
            odometer[position] %= charactersLength;
        } while (odometer[position++] == 0 && position < length);
    }
}

private static void WriteBruteForce(int[] odometer, char[] characters) {
    // Print backwards
    for (int i = odometer.Length - 1; i >= 0; i--) {
        Console.Write(characters[odometer[i]]);
    }
    Console.WriteLine();
}
私有静态字符[]个字符=
新字符[]{0',1',2',3',4',5',6',7',8',9',A',B',C',D',E',F',G',H',I',J'};
//长度:由bruteforce创建的字符串的长度
公共静态void performbuteforce(整数长度){
int charactersLength=个字符。长度;
int[]里程表=新int[长度];
长尺寸=(长)数学功率(字符长度,长度);
对于(int i=0;i=0;i--){
控制台.写入(字符[里程表[i]]);
}
Console.WriteLine();
}

这里我们所追求的不是严格意义上的排列——这不允许我们所追求的那种重复。不幸的是,我想不出正确的词,这就是为什么我选择了平淡的“GetAllMatches”我的答案中的方法名称。很抱歉将其与0-F混淆,它只是用来引用我们都能识别的东西。你可以用你自己的n-碱基数字来代替。@Jon:我想这个词是组合:)@Leppie:我也这么想,但事实并非如此。取一个集合{a,B,C}并返回{},{a},{B},{C},{a,B}等等。它是无序的,有不同的元素。嗯,哈哈,我不认为我的笔记本电脑是一个现实的蛮力机器为现代密码:)它更多的是为了大脑锻炼和乐趣。
class Program
{
    static void Main(string[] args)
    {
        BaseNCounter c = new BaseNCounter() { 
            CharSet = new char [] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }, 
            Power = 2};

        foreach(string cc in c.Count())
            Console.Write("{0} ,", cc);
        Console.WriteLine("");

        BaseNCounter c2 = new BaseNCounter()
        {
            CharSet = new char[] { 'x', 'q', 'r', '9'},
            Power = 3
        };
        foreach (string cc in c2.Count())
            Console.Write("{0} ,", cc);
        Console.Read();
    }
}
private static char[] characters =
    new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };

// length: The length of the string created by bruteforce
public static void PerformBruteForce(int length) {
    int charactersLength = characters.Length;
    int[] odometer = new int[length];
    long size = (long)Math.Pow(charactersLength, length);

    for (int i = 0; i < size; i++) {
        WriteBruteForce(odometer, characters);
        int position = 0;
        do {
            odometer[position] += 1;
            odometer[position] %= charactersLength;
        } while (odometer[position++] == 0 && position < length);
    }
}

private static void WriteBruteForce(int[] odometer, char[] characters) {
    // Print backwards
    for (int i = odometer.Length - 1; i >= 0; i--) {
        Console.Write(characters[odometer[i]]);
    }
    Console.WriteLine();
}