【问题标题】:C# Type of String Index字符串索引的 C# 类型
【发布时间】:2016-12-27 03:40:20
【问题描述】:

我需要访问intlong 无法处理的字符串索引中的一个非常大的数字。我不得不使用ulong,但问题是索引器只能处理int 类型。

这是我的代码,我已经标记了错误所在的行。任何想法如何解决这个问题?

       string s = Console.ReadLine();
        long n = Convert.ToInt64(Console.ReadLine());               
        var cont = s.Count(x => x == 'a');
        Console.WriteLine(cont);
        Console.ReadKey();

代码的主要思想是识别字符串中有多少'a's。我还有哪些其他方法可以做到这一点?

编辑:

我不知道字符串索引 Capicity 不能超过 int 类型。我通过用这条 linq 行替换它来修复我的 for 循环

var cont = s.Count(x => x == 'a');

现在因为我的字符串不能超过一定数量。那么我如何重复我的字符串以将其字符附加 1,000,000,000,000 次而不是使用此代码

for (int i = 0; i < 20; i++)
{
    s += s;
}

因为这段代码在字符串中生成随机字符数,如果我提出 20 可能会导致溢出,所以我需要调整它以重复自身以使 string[index] = n // 我在上面声明的 long。 例如,如果我的字符串输入是“aba”,n 是 10,那么字符串将是“abaabaabaa” // 总字符数 10

PS:我编辑了原始代码

【问题讨论】:

  • 我认为你的程序应该导致 OutOfMemory 异常
  • 根据this question,,字符串中的最大字符数不应超过有符号整数 - 因此您永远不需要访问需要 long 或特别是不需要无符号 long 的索引
  • Console.ReadLine() 返回超过 2.000.000 个字符?测试需要多长时间?无论如何,如果您真的想这样做,请使用foreach(Char c in s)
  • 如果你真的需要这样做,StringReader 类会满足你的需要吗?
  • Console.WriteLine(str.Count(s => s == 'a'))

标签: c# string indexing


【解决方案1】:

我假设您有一个编程任务或在线编码挑战,其中要求是“计算此 > 2 GB 文件中字母 'a' 的所有实例”。您的解决方案是一次读取内存中的文件,并使用允许值超过 2GB 的变量类型对其进行循环。

这会导致XY problem。首先,你不可能有一个内存那么大的数组,所以你不会达到需要uintlongulong 来索引它的地步。

改为使用StreamReader 以块的形式读取文件,例如Reading large file in chunks c# 中的说明。

【讨论】:

  • 我想我们赢了:)
  • 我希望人们更正我的代码以成为更好的程序员。我不想只是给他们问题,让他们为我解决问题。我可以很容易地用谷歌搜索解决方案。
  • @Omar 我不明白你的回答。您的代码无法修复,在我的回答中我解释了原因。你需要重新思考问题和你的解决方案。您为什么不编辑您的问题来解释您要解决的实际问题?我的意思是你显然不会从控制台读取 > 2 GB 的行。
  • @Omar 如果你有工作代码并且只是在寻找反馈/改进,我推荐Codereview SE
  • @Omar 对不起,不,只是根据我对您在问题中的解释的解释,我建议使用 StreamReader。现在我知道该链接的实际问题是什么,我会选择一种不同的方法。但这不是你的问题。 :) 也许你可以看看其他参赛者的提交,看看一些示例实现,以获得想法?一个提示:您不必在内存中构建无限字符串来解决这个问题。您可以“走过”它,直到达到要求的重复次数。
【解决方案2】:

您可以使用无限序列重复您的字符串。我没有对有效参数等进行任何检查。

static void Main(string[] args)
{
    long count = countCharacters("aba", 'a', 10);
    Console.WriteLine("Count is {0}", count);

    Console.WriteLine("Press ENTER to exit...");
    Console.ReadLine();
}

private static long countCharacters(string baseString, char c, long limit)
{
    long result = 0;

    if (baseString.Length == 1)
    {
        result = baseString[0] == c ? limit : 0;
    }
    else
    {
        long n = 0;
        foreach (var ch in getInfiniteSequence(baseString))
        {
            if (n >= limit)
                break;

            if (ch == c)
            {
                result++;
            }
            n++;
        }
    }

    return result;
}

//This method iterates through a base string infinitely
private static IEnumerable<char> getInfiniteSequence(string baseString)
{
    int stringIndex = 0;
    while (true)
    {
        yield return baseString[stringIndex++ % baseString.Length];
    }
}

对于给定的输入,结果是 7

【讨论】:

    【解决方案3】:

    我强烈建议您重新考虑执行此操作的方式,但快速解决方法是改用 foreach 循环:

    foreach(char c in s)
    {
        if (c == 'a')
            cont++;         
    }
    

    使用 Linq 的替代方案:

    cont = s.Count(c => c == 'a');
    

    我不确定n 应该做什么。根据您的代码,它限制了字符串长度,但您的问题从未提及原因或目的。

    【讨论】:

      【解决方案4】:

      我需要在字符串的索引中访问一个非常大的数字 int, long 无法处理

      这个说法不正确

      c# 字符串的最大长度是int.Max,因为string.Length 是一个整数并且受此限制。你应该可以做到

      for (int i = 0; i <= n; i++)
      

      【讨论】:

        【解决方案5】:

        字符串的最大长度不能超过int 的大小,因此使用ulonglong 来索引字符串确实没有意义。

        简单地说,你试图解决错误的问题。

        如果我们忽略程序在构建如此长的字符串时可能会导致内存不足异常的事实,您可以通过切换到int 而不是ulong 来简单地修复您的代码:

        for (int i = 0; i <= n; i++)
        

        话虽如此,您也可以使用 LINQ 来执行此操作:

        int cont = s.Take(n + 1).Count(c => c == 'a');
        

        现在,在您问题的第一句话中,您说明了这一点:

        我需要访问 int 和 long 无法处理的字符串索引中的一个非常大的数字。

        这是完全没有必要的,因为字符串的任何合法 index 都将适合 int

        【讨论】:

          【解决方案6】:

          如果您需要对超过 .NET 中字符串最大长度的某些输入执行此操作,则需要更改方法;使用Stream 而不是尝试将所有输入读入string

          char seeking = 'a';
          ulong count = 0;
          
          char[] buffer = new char[4096];
          using (var reader = new StreamReader(inStream))
          {
              int length;
              while ((length = reader.Read(buffer, 0, buffer.Length)) > 0)
              {
                  count += (ulong)buffer.Count(c => c == seeking);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2010-11-08
            • 2019-12-12
            • 1970-01-01
            • 1970-01-01
            • 2021-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-08-29
            • 2019-11-29
            相关资源
            最近更新 更多