【问题标题】:C# Finding "connected" permutationsC# 查找“连接”排列
【发布时间】:2019-04-29 09:37:46
【问题描述】:

我正在处理一个字典表,需要找出一个单词中所有可能的字符组合。感谢https://codereview.stackexchange.com/questions/28248/implement-a-function-that-prints-all-possible-combinations-of-the-characters-in,到目前为止我的工作如下:

    public List<string> findAllOccurance(string str)
    {
        var results = from e in Range(0, BigInteger.Pow(2, str.Length))
             let p =
                 from b in Enumerable.Range(1, str.Length)
                 select (e & BigInteger.Pow(2, b - 1)) == 0 ? (char?)null : str[b - 1]
             select string.Join(string.Empty, p);

        return results.ToList();
    }

    public IEnumerable<BigInteger> Range(BigInteger start, BigInteger count)
    {
        while (count-- > 0)
        {
            yield return start++;
        }
    }

将“abc”传递给上述函数将返回:

a
b
ab
c
ac
bc
abc

问题是我实际上只想找出“原始顺序”中的“连接”排列,例如“abc”应该只返回

a
b
c
ab
bc
abc

有人知道我应该改变什么来实现上述目标吗?

【问题讨论】:

  • @SaniSinghHuttunen - OP 想要“连接”字符 - “a”和“c”由“b”分隔。基本上需要的是长度为 1 到全长的所有子字符串的列表 - 这可以通过两个 for 循环轻松实现。
  • 给定一个“abab”的起始字符串 - 你的预期结果是什么?
  • @PaulF 我猜如果我理解 OP 并且他处理重复的案例只保留具有连续字符的唯一案例,那么接受的结果将是 a、b、ab、ba、aba、bab、abab。
  • @Dblaze47 没错,这就是我想要实现的目标,包括消除重复的部分,但“连接”是我遇到的麻烦。

标签: c# permutation


【解决方案1】:

通过“连接”排列 - 您实际上是在查找从长度 1 到字符串全长的所有子字符串。这可以通过两个 for 循环轻松完成。可以使用 Linq 的 Distinct() 方法删除重复项。

public List<string> findAllOccurance(string str)
{
    List<string> result = new List<string>();
    for (int i = 1; i <= str.Length; i++)
    {
      for (int j=0; j <= str.Length-i; j++)
        result.Add(str.Substring(j,i));
    }
    return result.Distinct().ToList();
}

注意——如果你真的想返回一个空字符串——你可以修改外部循环以从 0 开始,或者在创建列表实例后简单地手动添加它。修改循环将导致添加 str.Length 空字符串以及 Distinct() 的更多工作,当您知道您永远只希望返回 1 个空字符串时。

List<string> result = new List<string>();
result.Add(String.Empty);
for (int i = 1; i <= str.Length; i++)
.....

【讨论】:

    【解决方案2】:

    我不知道我对“连接”的理解是否正确...也许您可以简单地检查潜在结果是否是原始字符串的一部分...像这样:

    public List<string> findAllOccurance(string str)
    {
        var results = from e in Range(0, BigInteger.Pow(2, str.Length))
             let p =
                 from b in Enumerable.Range(1, str.Length)
                 select (e & BigInteger.Pow(2, b - 1)) == 0 ? (char?)null : str[b - 1]
             let p2 = string.Join(string.Empty, p)
             where str.Contains(p2)
             select p2;
    
        return results.ToList();
    }
    
    public IEnumerable<BigInteger> Range(BigInteger start, BigInteger count)
    {
        while (count-- > 0)
        {
            yield return start++;
        }
    }
    

    【讨论】:

      【解决方案3】:

      对于您的代码,您正在执行按位运算以查找所有可能的子集。对于abc 的情况,您的字符串长度为 3。因此可能的子集 = 2 ^ 3 = 8。将它们写下来并将最右边的位与最左边的索引匹配:

      Possible cases: 
      0 0 0     // gives nothing
      0 0 1     // gives 'a' (valid)
      0 1 0     // gives 'b' (valid)
      0 1 1     // gives 'ab' (valid)
      1 0 0     // gives 'c' (valid)
      1 0 1     // gives 'ac' (invalid as there is a 0 inbetween and not connected)
      1 1 0     // gives 'bc' (valid)
      1 1 1     // gives 'abc' (valid)
      

      以上是我所理解的关于你被认为是连接的内容。您可以通过两个循环轻松地执行检查:

      int max_size = BigInteger.Pow(2, str.Length);
      int str_size = str.Length;
      for(int i = 0; i < max_size; ++i) 
      { 
          string ans = "";
          for(j = 0; j < str_size; ++j) 
         { 
            // We check if the jth bit is set, we print the jth element from the string.
             if(i & (1 << j)) 
                 ans += str[j];
             } 
             else {
                 if(ans.Length > 0){
                     // this means we have already added a character and then the next consecutive bit is '0'
                     ans = "";
                     break;
                 }
             }
            if(ans != ""){
                 Console.Writeline(ans); // we print the set. you can control this anyway you want.
            } 
         }   
      } 
      

      【讨论】:

      • 感谢这个 Dblase47,你能帮我在这里做一些语法检查吗?我尝试修复一些简单的问题,例如 int jif(i &amp; (1 &lt;&lt; j)) {,但 if 显示错误,提示无法将 int 转换为 bool。
      • 检查是否 (1 0
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-03
      • 1970-01-01
      • 2021-05-12
      • 2020-11-29
      • 1970-01-01
      • 2020-09-04
      • 2010-11-10
      相关资源
      最近更新 更多