Thread: Rearranging a string... and a glitch

  1. #1
    Registered User
    Join Date
    Sep 2002
    Posts
    417

    Rearranging a string... and a glitch

    Here's what I want it to do:

    the left column represents the new string being assigned, the right is the source, before the digits are rearranged (that would work only if it was 15 characters long):

    Code:
    sOutput      Value
    sOutput[x]  sInput[x]
    0		1
    1		3
    2		5
    3		7
    4		9
    5		11
    6		13
    7		15
    8		0
    9		2
    10		4
    11		6
    12		8
    13		10
    14		12
    15		14
    For example: sOutput[1] has the same value as sInput[3]... My method for doing this is as follows:

    Code:
    void scramble()
    {
    	char sInput[1024];
    	char sOutput[1024];
    	int iLength = 0;
    	int i = 0, x = 0, y = 0, z = 0;
    
    	cout << "What message do you want to scramble?\n";
    	cin.get (sInput, 1024);
    	cin.ignore(1024, '\n');
    
    	iLength = strlen( sInput);
    	strrev(sInput);
    
    
    	x = 1;
    
    	for (i = 0; (i<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[i] = sInput[x];
    		x = x + 2;
    	}
    
    	x = 0;
    
    	for (i; (i<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[i] = sInput[x];
    		x = x + 2;
    	}
    
    	sOutput[i] = '\0';
    
    	cout << sOutput << endl << endl;
    
    	
    // 1 2 3 4 5 is an input example
    // 1 3 5 2 4 is the scrambled example
    // 4 2 5 3 1 is what it looks like after strrev
    }
    All that works fine... unless you input a string at least 10 characters (0123456789 won't work, but 123456789 will.)

    If you input 10 or more characters, it gives you mostly garbage characters.

    Also, I can't think of a simple way to descramble that so that 42531 becomes 13524 (strrev would work for that part), but then I need 13524 to be able to become 12345... so it would work both ways.

  2. #2
    Registered User
    Join Date
    Sep 2002
    Posts
    417

    Partially figured out

    I just realized it has nothing to do with 10 at all... if the length of the string is even, then it returns garbage. If the length is odd, then it works fine.

    Is there any way to put that all in one for loop instead of 2?

    Any ideas? Thanks so much!

  3. #3
    Yes. To combine them, just use modulo to check whether it is even.

    Here is an example:
    [CODE]
    for (int i = 0; i < 18; i++) {
    if (i % 2) {
    cout << i << "Is even" << endl;
    } else {
    cout << i << "Is odd" << endl;
    }
    }
    Compilers:
    GCC on Red Hat 8.1 (Primary)
    GCC on Mac OS X 10.2.4 (Secondary)

    Others:
    MinGW on XP

  4. #4
    The code above would also (as far as I can see) solve your garbage problem.
    Compilers:
    GCC on Red Hat 8.1 (Primary)
    GCC on Mac OS X 10.2.4 (Secondary)

    Others:
    MinGW on XP

  5. #5
    I have also been wondering this for awhile, and seeing as you use it, what does cin.ignore(int,char) do?
    Compilers:
    GCC on Red Hat 8.1 (Primary)
    GCC on Mac OS X 10.2.4 (Secondary)

    Others:
    MinGW on XP

  6. #6
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    oh... that... that makes it so that it won't go past a certain point, so it ignores anything in the input after a '\n' character or after so many characters... usually I use cin.ignore(80,'n');

    So how do I use your code? I know what you mean with the modulus, but I don't know how to implement it... I had a hard enough time writing out how to scramble it on paper so that I could write a program to do it... here's my code again:

    Code:
    x = 1;
    
    	for (i = 0; (i<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[i] = sInput[x];
    		x = x + 2;
    	}
    
    	x = 0;
    
    	for (i; (i<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[i] = sInput[x];
    		x = x + 2;
    	}
    
    	sOutput[i] = '\0';
    thats just the for loop part that rearranges sInput and saves it as sOutput

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Try this.
    Code:
    	x = 1;
    
    	for (i = 0; (x<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[i] = sInput[x];
    		x = x + 2;
    	}
    
    	x = 0;
    
    	for (i; (x<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[i] = sInput[x];
    		x = x + 2;
    	}

  8. #8
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    Thanks, swoopie & inquirer! I never thought of that!

    Swoopie, could you help me reverse the function of your fix, so it takes the scrambled and changes it back?

  9. #9
    Code:
    for (i=0, x=0; (i<iLength) && (sInput[x] != '\0'); i++, x++){
      if (i%2){
        sOutput[iLength/2+x] = sInput[i];
      } else {
        sOutput[x]=sInput[i]; 
      }
    }
    I think this works... Let me know if it doesn't.
    This also would optimize it, i think.
    ~Inquirer
    Compilers:
    GCC on Red Hat 8.1 (Primary)
    GCC on Mac OS X 10.2.4 (Secondary)

    Others:
    MinGW on XP

  10. #10
    Reversing it would look something like this:
    Code:
    for (i=0, x=0; (i<iLength) && (sInput[x] != '\0'); i++, x++){
      if (i%2){
        sUnscrambled[i] = sScrambled[iLength/2+x];
      } else {
        sUnscrambled[i] = sScrambled[x]; 
      }
    }
    I think.
    Compilers:
    GCC on Red Hat 8.1 (Primary)
    GCC on Mac OS X 10.2.4 (Secondary)

    Others:
    MinGW on XP

  11. #11
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    Originally posted by Inquirer
    Code:
    for (i=0, x=0; (i<iLength) && (sInput[x] != '\0'); i++, x++){
      if (i%2){
        sOutput[iLength/2+x] = sInput[i];
      } else {
        sOutput[x]=sInput[i]; 
      }
    }
    I think this works... Let me know if it doesn't.
    This also would optimize it, i think.
    ~Inquirer
    No, that gives me more garbage characters.

    The way swoopie did it works fine, but I don't know how to reverse that without going crazy :lol:

  12. #12
    Oh well I tried!
    Compilers:
    GCC on Red Hat 8.1 (Primary)
    GCC on Mac OS X 10.2.4 (Secondary)

    Others:
    MinGW on XP

  13. #13
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    thanks, you were a big help... but can you figure out how to descramble it for me?

    Code:
    	x = 1;
    
    	for (i = 0; (x<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[i] = sInput[x];
    		x = x + 2;
    	}
    
    	x = 0;
    
    	for (i; (x<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[i] = sInput[x];
    		x = x + 2;
    	}

  14. #14
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Trauts, here one way.
    Code:
    void descramble(char *sInput, char *sOutput)
    {
    	int i, x, iLength;
    
    	iLength = strlen( sInput);
    
    	x = 1;
    
    	for (i = 0; (x<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[x] = sInput[i];
    		x += 2;
    	}
    
    	x = 0;
    
    	for (; (x<iLength) && (sInput[x] != '\0'); i++)
    	{
    		sOutput[x] = sInput[i];
    		x += 2;
    	}
    
    	sOutput[i] = '\0';
    	strrev(sOutput);
    	cout << sOutput << endl << endl;
    }
    sInput is the string to be descrambled.
    Last edited by swoopy; 10-28-2002 at 10:42 PM.

  15. #15
    Registered User
    Join Date
    Sep 2002
    Posts
    417
    many thanks!

Popular pages Recent additions subscribe to a feed