资本化的排列

时间:2009-05-25 04:31:47

标签: c# .net string capitalization

我想建立一个列表,其中包含单词大写的所有可能排列。所以它会是

List<string> permutate(string word)
{
    List<string> ret = new List<string>();
    MAGIC HAPPENS HERE
    return ret;
}

所以说我加入“快乐”我应该得到一个

的数组

{快乐,快乐,快乐,快乐,快乐,快乐...哈普,哈普,快乐,快乐}

我知道有很多功能会把第一个字母大写,但我该如何在字中做任意字母?

8 个答案:

答案 0 :(得分:8)

如果将字符串转换为char数组,则可以修改单个字符。这样的事情应该可以解决问题...

public static List<string> Permute( string s )
{
  List<string> listPermutations = new List<string>();

  char[] array = s.ToLower().ToCharArray();
  int iterations = (1 << array.Length) - 1;

  for( int i = 0; i <= iterations; i++ )
  {
    for( int j = 0; j < array.Length; j++ )
    array[j] = (i & (1<<j)) != 0 
                  ? char.ToUpper( array[j] ) 
                  : char.ToLower( array[j] );
    listPermutations.Add( new string( array ) );
  }
  return listPermutations;
}

答案 1 :(得分:1)

请记住,虽然接受的答案是将任意字母大写的最直接方式,但如果要在同一组字母上重复更改大小写(例如,“快乐”中的32次并且指数级增长更长的单词),将字符串转换为char [],设置相应的字母,并从数组中构造字符串会更有效。

答案 2 :(得分:1)

要“置换”你的字符串(从技术上讲,这不是排列,因为你没有改变任何顺序,但我不想被视为一个* l-retentive :-),我会使用递归方法,它基本上“置换”字符串减去第一个字符,并将它们附加到该字符的上下变量。

有点像(在C中,我的C#并不是真的达到标准,所以你必须转换它):

#include <stdio.h>
#include <string.h>

static void permute (char *prefix, char *str) {
    char *newPrefix;

    /* End of string, print and return. */

    if (*str == '\0') {
        printf ("%s\n", prefix);
        return;
    }

    /* Allocate space for new prefix. */

    if ((newPrefix = malloc (strlen (prefix) + 2)) == NULL) {
        printf ("ERROR: Cannot allocate memory.\n");
        return;
    }

    /* Do lowercase/sole version and upper version if needed. */

    sprintf (newPrefix, "%s%c", prefix, *str);
    permute (newPrefix, &(str[1]));

    if (islower (*str) {
        sprintf (newPrefix, "%s%c", prefix, toupper(*str));
        permute (newPrefix, &(str[1]));
    }

    /* Free prefix and return. */

    free (newPrefix);
}

int main (int argc, char *argv[]) {
    char *str, *strPtr;

    /* Check and get arguments. */

    if (argc < 2) {
        printf ("Usage: permute <string to permute>\n");
        return 1;
    }

    if ((str = malloc (strlen (argv[1]) + 1)) == NULL) {
        printf ("ERROR: Cannot allocate memory.\n");
        return 1;
    }
    strcpy (str, argv[1]);

    /* Convert to lowercase. */
    for (strPtr = s; *strPtr != '\0'; strPtr++)
        *strPtr = toupper (*strPtr);

    /* Start recursion with empty prefix. */

    permute ("", str);

    /* Free and exit. */

    free (str);
    return 0;
}

"permute Pax1"运行此项会返回:

pax1
paX1
pAx1
pAX1
Pax1
PaX1
PAx1
PAX1

答案 3 :(得分:1)

我能够创建一个执行此操作的控制台应用程序。

 public static class Program
{
    static void Main()
    {
        Console.WriteLine("Enter string");
        string value = Console.ReadLine();

        value = value.ToLower();

        List<string> list = new List<string>();

         var results =
             from e in Enumerable.Range(0, 1 << value.Length)
             let p =
             from b in Enumerable.Range(0, value.Length)
             select (e & (1 << b)) == 0 ? (char?)null : value[b]
             select string.Join(string.Empty, p);

        foreach (string s in results)
        {
            string newValue = value;
            s.ToLower();
            foreach(char c in s)
            {
                var Old = c.ToString().ToLower();
                var New = c.ToString().ToUpper();
                newValue=ReplaceFirstOccurrence(newValue, Old, New);
            }
            list.Add(newValue);
        }

        foreach(string s in list)
        {
            Console.WriteLine(s);
        }

        Console.ReadKey();
    }

    public static string ReplaceFirstOccurrence(string Source, string Find, string Replace)
    {
        int Place = Source.IndexOf(Find);
        string result = Source.Remove(Place, Find.Length).Insert(Place, Replace);
        return result;
    }    
}

我得到了字符串中所有可能的字符子集的列表,然后为每个子集中的每个字符,用初始字符串中的大写字母替换了它们,然后列出了这些字符。必须具有自定义的替换功能作为普通字符串。替换将替换出现的任何字符。

这可能不是最干净的代码,但是可以完成工作。这是作为动态搜索加密字段的一种方式而提出的,我想看看那真的是多么疯狂。

答案 4 :(得分:0)

松散地说,如下所示。我可能会将我的范围缩小一个,但这个想法很合理。

def cap_n(in_str, pos):
  leading = in_str.substr(0, pos-1)
  trailing = in_str.substr(pos+1) # no second arg implies to end of string
  chr = in_str[pos].to_uppercase()
  return leading + chr + trailing

答案 5 :(得分:0)

使用按位运算。对于长度为N的字,您需要一个由N位表示的整数类型。如果这个词更长 - 拆分它。迭代从0到2 N -1的值,并检查从0到N-1的每个位。如果该位为1 - upcase(Char.ToUpper())对应于该位的字母。

这种方法比递归算法更好,因为它不会在长字上出现堆栈溢出。

答案 6 :(得分:0)

假设:

1)你不太关心这是O(n * 2 ^ n)......虽然我很想知道:这类问题最好的渐近运行时间是什么?

2)您的输入全部为小写。

3)您的输入是&lt; 32个字符长。 (置换计数器中的可用位数,i)

    List<string> permutate(string word)
{
    List<string> ret = new List<string>();

// MAGIC HAPPENS HERE
Dictionary<char,char> toUppers = new Dictionary<char,char>(26);
toUppers.Add('a', 'A');
toUppers.Add('b', 'B');
toUppers.Add('c', 'C');
toUppers.Add('d', 'D');
toUppers.Add('e', 'E');
toUppers.Add('f', 'F');
toUppers.Add('g', 'G');
toUppers.Add('h', 'H');
toUppers.Add('i', 'I');
toUppers.Add('j', 'J');
toUppers.Add('k', 'K');
toUppers.Add('l', 'L');
toUppers.Add('m', 'M');
toUppers.Add('n', 'N');
toUppers.Add('o', 'O');
toUppers.Add('p', 'P');
toUppers.Add('q', 'Q');
toUppers.Add('r', 'R');
toUppers.Add('s', 'S');
toUppers.Add('t', 'T');
toUppers.Add('u', 'U');
toUppers.Add('v', 'V');
toUppers.Add('w', 'W');
toUppers.Add('x', 'X');
toUppers.Add('y', 'Y');
toUppers.Add('z', 'Z');

char[] wordChars = word.ToCharArray();
int len = wordChars.Length;

// iterate the number of permutations
for(int i = 0; i < 2^len; i++) {
    char[] newWord = new char[len]();

    // apply "i" as a bitmask to each original char
    for(int n = 0; n < newWord.Length; n++) {
        if((1 << n) & i != 0) {
            newWord[n] = toUppers[wordChars[n]]; // or skip the dictionary and just call Char.ToUpper(wordChars[n])
        } else {
            newWord[n] = wordChars[n];
        }
    }
    ret.Add(new String(newWord));
}

    return ret;
}

注意:我没有编译或测试此代码。这也是实现上面提到的尖锐的比较。

答案 7 :(得分:0)

如果顺序无关紧要,则可以尝试 Linq 。我们列举了[0..2**word.Length]范围内的所有二进制数。并将每个数字视为 mask 0-小写,1-大写。我们拥有的happy的FDor实例

mask      string
----------------
00000  ->  happy
00001      Happy
00010      hAppy
00011      HAppy
00100      haPpy
00101      HaPpy
...
11111      HAPPY

代码:

  using System.Linq;

  ... 

  List<string> permutate(string word) =>
    Enumerable
      .Range(0, 1 << word.Length)
      .Select(mask => string.Concat(word.Select((c, i) => (mask & (1 << i)) == 0 
         ? char.ToLower(c) 
         : char.ToUpper(c))))
      .ToList();

演示:

  Console.Write(string.Join(", ", permutate("happy")));

结果:

happy, Happy, hAppy, HAppy, haPpy, HaPpy, hAPpy, HAPpy, hapPy, HapPy, hApPy, HApPy, haPPy, HaPPy, hAPPy, HAPPy, happY, HappY, hAppY, HAppY, haPpY, HaPpY, hAPpY, HAPpY, hapPY, HapPY, hApPY, HApPY, haPPY, HaPPY, hAPPY, HAPPY