生成两个字符串之间的范围[AA] - > [CD]或[CCC] - > [DMK]

时间:2017-12-07 21:10:43

标签: c# .net linq

我想在两组之间生成一串字符串,可以是1个字母[A] - > [F],2个字母,如[AA] - > [CD]或使用c#的任何其他长度,如3或4个字母。

例如,我可以指定起始值和结束值,它将生成序列。

从[AA]到[CD]应生成

AA
AB
AC
AD

BA
BB
BC
BD

CA
CB
CC
CD

我尝试使用base-26算法生成所需的序列,但未能获得所需的输出。

string from ="AA";
string to = "CD";
IEnumerable<string> mysequence = Enumerable.Range(ConvertNumber(from), ConvertNumber(to) - ConvertNumber(from)).Select(ConvertAlpha).ToList();

public static string ConvertAlpha(int value)
{
    const int a = (int)'A';
    value = value - 1;
    var returnValue = new StringBuilder();
    while (value > -1)
    {
        var remainder = value % 26;
        returnValue.Insert(0, (char)(a + remainder));
        value = value / 26 - 1;
    }
    return returnValue.ToString();
}

public static int ConvertNumber(string value)
{
    const int a = (int)'A' - 1;
    int returnValue = 0;
    foreach (var character in value.ToUpper())
    {
        returnValue *= 26;
        returnValue += (int)character - a;
    }
    return returnValue;
}

2 个答案:

答案 0 :(得分:1)

使用递归(但是使用蛮力而不是优雅):

find(get?int

答案 1 :(得分:1)

您描述的问题比仅将base-26表示转换为整数,进行一些计算,然后转换回来更难。你的alpha字符串不一定是26。例如,您说要给定AACD,您要生成

AA, AB, AC, AD
BA, BB, BC, BD
CA, CB, CC, CD

你真正拥有的是一个base-4系统,它使用字符ABCD来表示数字0123。你在这里说的是你想要生成从00到33的所有2位数,4号基数。

鉴于CCC => DMK,它是使用数字CM的base-11系统。从您的描述中不清楚您是否想要:

CCC, CCD, CCE ... CCK
CDC, CDD, CDE ... CDK
...

或者如果你想要

CCC, CCD, CCE ... CCM
CDC, CDD, CDE ... CDM
...

如果你想要前者,那么每个数字位置都是不同的基础,事情变得更加复杂。

如何定义内容会改变编写代码以生成值的方式。

无论您想要如何解释您的Alpha值,都清楚您的base-26转换函数不正确。

您从int转换为string有一些错误。特别是,从值中减去1会给你带来麻烦。你可以看到,如果你将0传递给函数。结果将是一个空字符串。

这是一个正确的功能:

static string ConvertToBase26(int value)
{
    const int a = (int)'A';
    var result = new StringBuilder();
    do
    {
        var remainder = value % 26;
        value /= 26;
        result.Insert(0, (char)(a + remainder);
    } while (value > 0);
    return result.ToString();
}

由于从事物中减去1,您从base26到整数的转换具有类似的错误。请注意,A的行为与0相同。纠正的功能:

static int ConvertFromBase26(string value)
{
    const int a = (int)'A';
    int result = 0;
    foreach (var c in value.ToUpper())
    {
        result = (result * 26) + (c - a);
    }
    return result;
}

我建议重命名基本转换功能。您的ConvertAlpha函数将整数转换为基数为26的字符串。这一点在名称中根本不清楚,因为人们可能会误解并且#B; ConvertAlpha&#34;表示&#34; ConvertFromAlpha&#34;。我建议使用ConvertToBase26ConvertFromBase26,这些更明确,更明确。