【问题标题】:Find subsets of a string but just which is neighbours找到一个字符串的子集,但它是邻居
【发布时间】:2020-01-09 20:32:02
【问题描述】:

我正在尝试提取子集,但不是全部,只是一个 邻居。下面的简单例子;

输入:“123456789”

结果:

3.Level 子集:out3 : [123,234,345,456,567,678,789]
..
5.Level子集:out5:[12345,23456,34567,45678,56789]
..
8.Level子集:out8 :[12345678,23456789]

结果 = [out1,..,out5,..out8]

如果有一个很酷的解决方案,如果它可以是字符串操作,那就太好了。

非常感谢

【问题讨论】:

  • 我不了解您的示例输入和输出。也许您可以将其表达为某些代码可能会调用您想象的方法并输出其结果,然后显示该文本输出的样子?
  • 谢谢,我编辑了一些,我想找到子集,但不是全部,只是我展示的示例。

标签: c# arrays string subset


【解决方案1】:

您需要进行额外的错误检查以查看 level 是否比字符串的长度等长。

public static void Main(string[] args)
{
    var results = FindSubsets("123456789", 3);
    Console.Read();
}

public static List<string> FindSubsets(string data, int level)
{
    if (level > data.Length || level < 1)
        return null;

    var results = new List<string>();
    for (int i = 0; i < data.Length - level + 1; i++)
    {
        results.Add(data.Substring(i, level));
    }
    return results;
}

编辑:

添加了针对level的字符串长度检查。

编辑2:

如果要查找特定长度的子集,可以执行以下操作。创建一个List&lt;int&gt;,其中包含您要查找其子集的所有级别,然后重复调用该函数。例如,假设您要查找级别 3、5 和 8 的子集。然后:

var data = "123456789";
var levels = new List<int>() { 3, 5, 8 };

var results = new List<List<string>>();
foreach(var level in levels)
{
    results.Add(FindSubsets(data, level));
}

【讨论】:

  • 感谢您的快速解决方案,它正在工作。在我做出正确的解决方案后,我将对此进行一些测试。 :) 非常感谢。
【解决方案2】:
public IEnumerable<string> GetSubsets(string input, int length)
{
    if (string.IsNullOrEmpty(input)) 
        throw new ArgumentException("Invalid string");

    if (length <= 0) 
        throw new ArgumentException("Length must be greater than 0.");

    if (length > input.Length) 
        throw new ArgumentException("The desired set length is longer than the string");

    for(int i = 0; i<=input.Length - length;i++)
    {
       yield return input.Substring(i, length);
    }
}

【讨论】:

    【解决方案3】:

    是的,这可以使用正则表达式来完成:

    string input = "123456789";
    int size = 3; // set to whatever
    MatchCollection split = Regex.Matches(input, @$"\d{{size}}");
    string delimited = string.Join(",", split);
    

    或者作为扩展方法:

    public static string Delimit(this string s, int size)
    {
        MatchCollection split = Regex.Matches(input, @$"\d{{size}}");
        return delimited = string.Join(",", split);
    }
    

    【讨论】:

    • 我试过了,但是这段代码给出了这个结果; [1,456789]。但我想要这样 [123,234,345,456,567,678,789]
    • @mocco 是的,您需要使用Regex.Matches 而不是Regex.Split。答案已更新。
    【解决方案4】:

    我基本上只是强行回答:

    import java.util.ArrayList;
    
    public class MyClass {
    
        public static ArrayList<ArrayList<String>> getAllSubets(String input){
            ArrayList<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
    
            ArrayList<String> out = new ArrayList<String>();            
    
            for(int i= input.length(); i>=0; i--){
                int z = i;
                for(int j = 0; j+i<input.length() ;j++){
                    z++;
                    out.add(input.substring(j, z));
                }  
            }
    
            list.add(out);
    
            return list;
    
        }
    
    
    
        public static void main(String args[]) {
            System.out.println(MyClass.getAllSubets("123456789"));
        }
    }
    

    输出:

    [[123456789, 12345678, 23456789, 1234567, 2345678, 3456789, 123456, 234567, 345678, 456789, 12345, 23456, 34567, 45678, 56789, 1234, 2345, 3456, 4567, 5678, 6789, 123, 234, 345, 456, 567, 678, 789, 12, 23, 34, 45, 56, 67, 78, 89, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
    

    这是一个有趣的问题,很容易被索引绊倒。

    【讨论】:

      【解决方案5】:

      查找所有子集:

      var Input = "123456789";
      var Result = Enumerable
          .Range(1, Input.Length)
          .Select(i => Enumerable
              .Range(0, Input.Length - i + 1)
              .Select(j => Input.Substring(j, i)))
          .ToList();
      

      要限制在某些级别,例如 3、5 或 8,只需在执行工作之前进行过滤,如下所示:

      var Levels = new List<int>{ 3, 5, 8 };
      var Input = "123456789";
      var Result = Enumerable
          .Range(1, Input.Length)
          .Where(i => Levels.Contains(i)) // Filter the levels you need before constructing the subsets.
          .Select(i => Enumerable
              .Range(0, Input.Length - i + 1)
              .Select(j => Input.Substring(j, i)))
          .ToList();
      

      结果:

      123、234、345、456、567、678、789

      12345, 23456, 34567, 45678, 56789

      12345678, 23456789

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-24
        • 2017-11-06
        • 2012-06-25
        相关资源
        最近更新 更多