-3

I need to access a very large number in the index of the string which int and long can't handle. I had to use ulong but the problem is that the indexer can only handle the type int.

This is my code and I have marked the line where the error is located. Any ideas how to solve this?

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

The main idea of the code is to identify how many 'a's there are in the string. What are some other ways I can do this?

EDIT:

i didn't know that is the string index Capicity cant exceed the int type. and i fixed my for loop by replacing it with this linq line

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

now since my string can't exceed certain amount. so how i can repeat my string to append its char for 1,000,000,000,000 times rather than using this code

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

since this code is generating random char numbers in the string and if i raised the 20 may cause to overflow so i need to adjust it to repeat itself to make the string[index] = n // the long i declared above. so for example if my string input is "aba" and n is 10 so the string will be "abaabaabaa" // total chars 10

PS: I Edited the original code

Omar Alaa
  • 141
  • 2
  • 13
  • I think your program should cause OutOfMemory exception – M.kazem Akhgary Nov 11 '16 at 15:29
  • 1
    According to [this question,](http://stackoverflow.com/questions/140468/what-is-the-maximum-possible-length-of-a-net-string) the maximum characters in a string should not exceed even a signed integer - so you should never need to access an index that requires a long or escpecially not an unsigned long – Alfie Goodacre Nov 11 '16 at 15:30
  • 2
    `Console.ReadLine()` returns more than 2.000.000 characters? How long does it take to test that?. Anyway, if you really want to do it this way, use `foreach(Char c in s)` – Manfred Radlwimmer Nov 11 '16 at 15:30
  • If you really need to do it this way does the StringReader class do what you need? – Lee Willis Nov 11 '16 at 15:32
  • Console.WriteLine(str.Count(s => s == 'a')) – Rich Linnell Nov 11 '16 at 15:34
  • I Really Have no idea why people downvote my question and disallowing me from asking more questions. if i didn't know that string maximum index won't be greater than integer you can just say that ! i am new and i am learning and i don't know. so rather than downvoting you can just say that ! – Omar Alaa Nov 11 '16 at 15:40
  • I think most people operate on the fact that there are so many clues in the string documentation and class that the maximum number you can use for an index is really just an int so that it would be very odd for you to miss that fact completely. Most likely you have stated the problem incorrectly, and thus the downvotes. – Lasse V. Karlsen Nov 11 '16 at 15:41
  • @OmarAlaa Downvotes do not necessarily mean that it is a bad question, in this case I'm guessing it is bacause your question was very vague, badly formatted (we fixed that by now) and didn't give any context as to what you are trying to do (and why). – Manfred Radlwimmer Nov 11 '16 at 15:46
  • @OmarAlaa By the way, there is a topic on meta that might help you: [What can I do when getting “We are no longer accepting questions/answers from this account”?](http://meta.stackexchange.com/questions/86997/what-can-i-do-when-getting-we-are-no-longer-accepting-questions-answers-from-th) – Manfred Radlwimmer Nov 11 '16 at 15:48

6 Answers6

3

I assume you got a programming assignment or online coding challenge, where the requirement was "Count all instances of the letter 'a' in this > 2 GB file". You solution is to read the file in memory at once, and loop over it with a variable type that allows values over 2GB.

This causes an XY problem. You cannot have an array that large in memory in the first place, so you're not going to reach the point where you need a uint, long or ulong to index into it.

Instead, use a StreamReader to read the file in chunks, as explained in for example Reading large file in chunks c#.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • I think we have a winner :) – Manfred Radlwimmer Nov 11 '16 at 15:43
  • i want people to correct my code to be a better programmer. i don't want to just give them the problem for them to solve it for me. i can google the solution easily. – Omar Alaa Nov 11 '16 at 15:45
  • @Omar I don't understand your response. Your code is impossible to fix, and in my answer I explain why. You need to rethink the problem and your solution to it entirely. Why don't you edit your question to explain the actual problem you're trying to solve? I mean you're obviously not going to read a line of > 2 GB from the console. – CodeCaster Nov 11 '16 at 15:45
  • @Omar If you have working code and are simply looking for feedback / improvements, I recommend [Codereview SE](http://codereview.stackexchange.com/) – Manfred Radlwimmer Nov 11 '16 at 15:50
  • @CodeCaster you can check the problem here https://www.hackerrank.com/challenges/repeated-string its kind of forcing me to use a big index for the string. it must have it. – Omar Alaa Nov 11 '16 at 15:51
  • @Omar the point of that programming exercise is that you're **not** supposed to build the string in memory. The exercise was made that way precisely to generate strings that are too large to fit in memory. – CodeCaster Nov 11 '16 at 15:52
  • @CodeCaster and in generaly i don't give people the real problem because i don't want them to just simply solve the problem for me. i wanna try until my code works. in case my code has a big problem which will disallow it from working so then we can look through other answers for the main problem – Omar Alaa Nov 11 '16 at 15:54
  • @Omar you misinterpreted the description. `s.Length` is not up to 10e12. That's simply the length of an infinite version of s. You can get the index with `s[(int)(i%s.Length)]` – Manfred Radlwimmer Nov 11 '16 at 15:55
  • @Omar alright, I understand and appreciate that. You were just unlucky enough to choose an approach for this problem which isn't going to work at runtime, so you'll have to choose another one. – CodeCaster Nov 11 '16 at 15:56
  • @CodeCaster So the other way i am going to choose that you recommend is streamreader and i should study it now . aye ? – Omar Alaa Nov 11 '16 at 15:59
  • 1
    @Omar I'm sorry, no, it's just that from my interpretation of your explanation in your question I would recommend using a StreamReader. Now that I know what the actual problem is from that link, I'd choose a different approach. But that's not (in) your question. :) Maybe you could take a look at other contestant's submissions to see some example implementations, for ideas? One hint: you don't have to build the infinite string in memory to solve this. You can 'walk' over it until you reached the requested number of repetitions. – CodeCaster Nov 11 '16 at 16:01
  • @CodeCaster please take a look at the edit and see if i made it clear and if you can help me with that. – Omar Alaa Nov 11 '16 at 16:50
1

I highly recommend you rethink the way you are doing this, but a quick fix would be to use a foreach loop instead:

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

Alternative using Linq:

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

I'm not sure about what n is supposed to do. According to your code it limits the string length but your question never mentions why or to what end.

Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
1

You can repeat your string using an infinite sequence. I haven't added any check for valid arguments, etc.

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];
    }
}

For the given inputs, the result is 7

Chris Dunaway
  • 10,974
  • 4
  • 36
  • 48
0

i need to access a very large number in the index of the string which int, long can't handle

this statement is not true

c# string's max length is int.Max since string.Length is an integer and it is limited by that. You should be able to do

for (int i = 0; i <= n; i++)
Steve
  • 11,696
  • 7
  • 43
  • 81
0

The maximum length of a string cannot exceed the size of an int so there really is no point in using ulong or long to index into the string.

Simply put, you're trying to solve the wrong problem.

If we disregard the fact that the program is likely to cause an out of memory exception when building such a long string, you can simply fix your code by switching to an int instead of a ulong:

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

Having said that you can also use LINQ to do this:

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

Now, in the first sentence of your question you state this:

I need to access a very large number in the index of the string which int and long can't handle.

This is wholly unnecessary because any legal index of a string will fit inside an int.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
0

If you need to do this on some input that's longer than the maximum length of a string in .NET, you'll need to change your approach; use a Stream instead trying to read all input into a 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);
    }
}
Ade Stringer
  • 2,611
  • 17
  • 28