Hey guys :)
After a year of c++, teacher's announced we'll be learning C standard as well, starting with next semester.

So anyway, I've been looking through some examples and exercises in a book and found 2 problems I can't seem to solve. (At least not in C).

The first one goes like this: From a text file, read a string of rational numbers only once and determine the longest sequence of equal numbers, as well as the position at which that sequence begins.

Second: Read a string of numbers from a file and rearrange them so that the pair numbers will be at the beginning of the string and the impair at the end. The order of those substrings must be identical to the original string.

Now for the life of me I can't figure out the position thing in the 1st poblem and in the 2nd, not sure how should I move the numbers around efficiently.

Also, I don't know how to read elements from a file using C nor am I sure how I "print" them.

Any support would be great, hope I'm not bothering you too much ^_^

First, do you know how to read a file in C language? If not, here's a tutorial

The position in problem #1 can be interpreted a couple ways depending on how the file is formatted. If all the numbers are on one long string, then the position will be the character position on that line, for example: "1 2 2 3 3 3 4" the position will be 6 because the first 3 is in the 6th character position. If on separate lines

1
2
2
3
3
3
4

Then the position will be 3 because the first 3 in on the 3d line.

First, do you know how to read a file in C language? If not, here's a tutorial

The position in problem #1 can be interpreted a couple ways depending on how the file is formatted. If all the numbers are on one long string, then the position will be the character position on that line, for example: "1 2 2 3 3 3 4" the position will be 6 because the first 3 is in the 6th character position. If on separate lines

1
2
2
3
3
3
4

Then the position will be 3 because the first 3 in on the 3d line.

:D I understand that, but I didn't know how would I have to implement it so that I'd also get the position noot just the string lenght.

The lenght can be checked with a "for" I suppose. Keep the largest value. But how would I know at which position did the longest string start?

Oh and thanks for the file tutorial, it helped.

something like this should work (warning: untested)

max_sequence := 0
max_sequence_start := 0
for i from 0 to end of file:
     current_sequence_start := i
     flag = true;
     int count := 1
     while i < end of file AND flag == true:
          i++
          if sequence[i] != sequence[i-1]:
               flag := false
               i--
          else count++
     if count > max_sequence:
          max_sequence := count
          max_sequence_start := current_sequence_start

It's late here and I'm very likely to be forgetting something - someone please do correct me in that case :P

EDIT: I could be almost asleep and hence not perfectly able to understand but

for example: "1 2 2 3 3 3 4" the position will be 6 because the first 3 is in the 6th character position.

is that right? I mean isn't it 3rd position too ?

1 2 2 3 3 3 4  <-- string
^ ^ ^ ^ ^ ^ ^
0 1 2 3 4 5 6  <-- positions
      ^

I apologize if I have misunderstood

It's late here and I'm very likely to be forgetting something - someone please do correct me in that case :P

EDIT: I could be almost asleep and hence not perfectly able to understand but


is that right? I mean isn't it 3rd position too ?

1 2 2 3 3 3 4  <-- string
^ ^ ^ ^ ^ ^ ^
0 1 2 3 4 5 6  <-- positions
      ^

I apologize if I have misunderstood

We have no precise/exact definition of a "position". I was counting white-space (spaces and tabs) as positions.

Since you are not working on a homework problem, I found it a little interesting to code the first problem. There are many ways to program it, and as long as they all have the same result, each method if probably as correct as any other. Here's my effort. It only uses c++ for cout.

#include <iostream>
using std::cout;

struct val
{
    int value;
    int pos;
    int count;
};

int main()
{
    char str[] = "12 23 23 34 34 34 455";
    struct val* iarray = NULL;
    int arysize = 0;
    int pos = 0;
    int nm;
    int i;
    int n;
    int found = 0;
    int len = strlen(str);
    int counter = 0;
    // convert the string of numbers into an array of struct val
    // The array will contain only one entry for any given number,
    // along with the position at which the first value starts in the
    // string and the count of the number of times the number appears
    // in the string.  This algorithm will not work correctly if the sequence
    // of the same number appears more than once in the struct, such as 
    // "1 2 3 3 4 5 2 2 3 3";
    for(i = 0; i < len; )
    {
        // skip white space
        while( str[i] && isspace(str[i]) )
        {
            ++i;
            ++pos;
        }
        // convert ascii to int
        nm = 0;
        while(str[i] && isdigit(str[i]) )
        {
            nm = nm * 10 + str[i] - '0';
            ++i;
        }
        // check of value is alreay in the array.  If it is, then just
        // increment its counter.  If not, then expand the array and
        // start a new one.
        found = 0;
        for(n = 0; n < arysize; n++)
        {
            if( iarray[n].value == nm )
            {
                found = 1;
                iarray[n].count++;
                break;
            }
        }
        if(found == 0)
        {
            arysize++;
            iarray = (struct val *)realloc(iarray, arysize * sizeof(struct val));
            iarray[arysize-1].value = nm;
            iarray[arysize-1].pos = pos;
            iarray[arysize-1].count = 1;;
            pos = i;
        }
    }

//    for(i = 0; i < arysize; i++)
//        cout << iarray[i].value << " " << iarray[i].pos << "\n";

    // All we have to do not is pick out the struct val that contains the
    // largest count value.
    counter = iarray[i].count;
    struct val maxval = iarray[0];
    for(i = 1; i < arysize; ++i)
    {
        if( iarray[i].count > maxval.count )
        {
            maxval = iarray[i];
        }
    }
    cout << maxval.value << " " << maxval.pos << " " << maxval.count << "\n";
}

mrboolf: is that PASCAL code?

No it's some sort of pseudo code (like the one I'm used to read in school books - I apologize if it's not a common practice to use it)

I was counting white-space (spaces and tabs) as positions.

I was sure there was a logic explanation, although I was too sleepy to consider that :P. You were right and I was wrong, I'll refrain from posting until after a good sleep in the future ;)

Okay, so based on your support and with my (older) sister's help, I've done it and it seems to work:

#include <stdio.h>
#define NMax 100
#define IN_FILE "prob1.in"
#define OUT_FILE "prob1.out"

int n;
float a[NMax];

int main(void)
{
    FILE * fin = fopen( IN_FILE, "r" );
    FILE * fout = fopen( OUT_FILE, "w" );
    int i, poz, lung, poz_max, lung_max;
    
    fscanf( fin, "%d", &n );
    for( i=0; i<n; i++ )
	fscanf( fin, "%f", &a[i] );
    fclose( fin );
    
    if( n )
    {
		poz = poz_max = 0;
		lung = lung_max = 1;
	
		for( i=1; i<n; i++ )
		{
	    	if( a[i]==a[i-1] )
				lung+=1;
	    	else
	    	{
				if( lung>lung_max )
				{
		    		lung_max = lung;
		    		poz_max = poz;
				}
				poz = i;
				lung = 1;
	    	}
		}
	
    	if( lung>lung_max )
		{
	    	lung_max = lung;
	    	poz_max = poz;
		}
	
		fprintf( fout, "longest sequence starts at %d and it's lenght is %d.", poz_max, lung_max );
		fclose( fout );	
    }
    return 0;
}

also, we didn't study stuff like structures and pointers (not enough at least), so Ancient Dragon, your code was a bit tough to go through :D good thing for your comments.


Noow, I'd really like some help with the second one. Not sure what would be a good technique to rearrange those elements in that vector (string). But nothing too fancy please :)

This article has been dead for over six months. Start a new discussion instead.