Help in C

Discussion in 'Mac Programming' started by dvince2, Oct 17, 2007.

  1. dvince2 macrumors 6502

    dvince2

    Joined:
    Mar 6, 2007
    Location:
    Canada
    #1
    Hey everyone
    I'm in a beginners C class, and have been asked to return the number of each integer inputted from a file
    ie. 2 2 4 7 4 2 2 10 9 9 would return
    4 2
    2 4
    1 7
    1 10
    2 9

    I figured this would be easy... but we're not allowed to use arrays of any kind, and only can use printf and scanf from stdio.h

    Any help (even just a concept) of how to do this would be great. I don't want the program in C... just an idea how to start this :)
     
  2. lazydog macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #2
    Hi

    I guess you could use 2 for loops, one inside the other. The outer loop looks for the start of each number in the input string, and the inner loop counts the number of times that number occurs in the remainder of the string.

    b e n
     
  3. garethlewis2 macrumors 6502

    Joined:
    Dec 6, 2006
    #3
    Why oh why don't you students think for yourselves?

    This is what you need to do.

    In a loop of some type you need to read the first integer as a fixed size. This is your first number you look for. Then increase the file pointer by an integer size and read another number. If this matches the number you are looking for, increase that variable by one, until you reach the end of the file. Then reset the file pointer to the start + 1 where one is the size of an integer. Read the next number. Remember this could cause you a problem with a number you have already read, e.g. 2 in your example. So you need to use a case statement. Since you can't use an array you will have to limit the range of values in the file to something feasible, e.g. 20.

    This isn't a difficult problem, you just need to think before posting your homework assignment.
     
  4. John Jacob macrumors 6502a

    John Jacob

    Joined:
    Feb 11, 2003
    Location:
    Columbia, MD
    #4
    I don't see how a case statement would help there.

    Here's how I would do it.

    First use a while loop to read all the integers from the file. In this loop, use a counter so that we know the number of integers in the file, and use a variable that starts at zero, and which increases if the current integer exceeds that variable's value. This variable will hold the largest integer in the file.

    Now, use two for loops. The outer for loop starts at zero and goes upto the largest integer in the file. The inner for loop starts at zero and goes upto the number of integers in the file. In the inner loop, count the number of integers that are of the same value as the outer loop variable.

    In pseudocode:

    Code:
    int func(void)
    {
      int current, i, j, largest, total, count;
    
      largest = 0; total = 0;
      while (1)
      {
        current = getNextIntegerFromFile();
        if (current == -1)
          break;
        if (current > largest)
          largest = current;
        total++;
      }
    
      for (i = 0; i <= largest; i++)
      {
        count = 0;
        resetToStartOfFile();
    
        for (j = 0; j < total; j++)
        {
          current = getNextIntegerFromFile();
          if (current == i)
            count++;
        }
        if (count > 0)
          printf("Number of %d is %d\n", i, count);
      }
      return 0;
    }
    
    I have assumed that getNextIntegerFromFile reads the next integer from the file, and returns -1 if we have reached EOF. resetToStartOfFile resets the file read pointer to the beginning of the file.

    Of course, the problem with this algorithm is that we have to read through the file twice.
     
  5. toddburch macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #5
    Actually, the resetToStartOfFile is in the wrong place, and you will be reading (you need to read) the file largest + 1 times.

    Which, may be perfectly acceptable for this assignment; it's a beginning C class, not a 4th year optimization class.

    Todd
     
  6. John Jacob macrumors 6502a

    John Jacob

    Joined:
    Feb 11, 2003
    Location:
    Columbia, MD
    #6
    Oops, you're right. Silly me! :mad:

    I've edited my earlier post accordingly.
     
  7. lazydog macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #7
    I think you might be able to get rid of this step. All you need to do when reading in the numbers in the inner loop is check if it the number is greater than the index number in the outer loop. If it is you know you need to loop round again. Also if you keep track of the smallest number greater than the current outer loop index, you can 'skip' ahead to that number in the outer loop instead of stepping through the integers by 1 each time.

    Probably as clear as mud but I hope it helps.

    b e n
     
  8. GeeYouEye macrumors 68000

    GeeYouEye

    Joined:
    Dec 9, 2001
    Location:
    State of Denial
    #8
    If the maximum number is low, you could just have something like

    int ones, twos, threes, fours...;
    foreach number in file
    {
    switch (atoi(number))
    {
    case 1: ones++;
    ...
    }
    }

    And then print your output.
     
  9. toddburch macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #9
    I wish we got more background info on these questions.

    For instance, if this week's topic of interest was BIT FLAGS, then a solution using bit flags would be appropriate. If this week's topic was on searching a string for matching patterns, then those could have been emphasized in yet another solution.

    Or, perhaps next week's topic is array's, and this exercise was given to the student so he/she could gain an appreciation for the worth of an array.

    Todd
     
  10. ChrisA macrumors G4

    Joined:
    Jan 5, 2006
    Location:
    Redondo Beach, California
    #10
    Here is the solution I think is the "most cool".

    1) forget that these are numbers you are reading.
    they are simply strings seporated by white space.

    Write a function that will given on string, find it inside
    a second string and if found remove it from the
    second string. The function returns 1 if found else 0
    Searching and removing is easy if you use strstr and
    strcpy. I think you can do this function in 2 or 3 lines of code
    (hint strcpy(foobar[3], foobar[6]) cuts out a segment of
    the string foobar. strstr returns a pointer to the thing to
    be cut out.)
    use srttok to find first integer. Pass this and the whole
    string to above. Call self recursively until zero is returned
    keeping count of ones

    on zero returned print substring and counter

    You now have a sting with all occurances of the fist
    integer removed.
    Repeat until the sting us used up that is while(string[0])

    The above would actually count up words in a text book
    even if there were 10,000 different words because it uses
    the textbook itself as memory.

    Details are intensionally left out.

    The key here is that you don't need to keep track of what
    has been counted. delete it from the string as you count
     

Share This Page