Home > Mobile >  C reverse a string but printing numbers first
C reverse a string but printing numbers first

Time:10-13

I was given a project in class and almost have it finished, I am required to take a string of numbers and letters and return that string with the numbers printed first followed by the letters in reverse order (ex. abc123 should return 123cba). As of now my code returns a string with the numbers first and the original order of the letters (ex. abc123 returns 123abc). I would be able to do this with two loops however the assignment asks that my code only iterates though the initial string one time. Here is the code I have so far...

#include <iostream>
#include <string>
#include "QueType.h"
#include "StackType.h"
using namespace std;

int main ()
{
QueType<char> myQueue;
StackType<char> myStack;
string myString="hello there123";
char curchar;
string numbers, letters;


for (int i = 0; i < myString.length(); i  ) {
    if (isdigit(myString.at(i))) {
        myQueue.Enqueue(myString.at(i));
        myQueue.Dequeue(curchar);
        numbers  = curchar;
        //cout<<numbers<<endl;
    }
    else if (islower(myString.at(i))) {
        myStack.Push(myString.at(i));
        curchar = myStack.Peek();
        myStack.Pop();
        letters  = curchar;
        //cout<<curchar<<endl;
    }
    
}

cout<<(myString = numbers   letters)<<endl;

}

In my code, I have two .h files that set up a stack and a queue. With the given string, the code loops through the string looking to see if it sees a letter or number. With a number the spot in the string is then saved to a queue, and with a letter it is saved to the stack.

The only other way i can think of reversing the order of the letters is in the if else statement instead of having char = myStack.Peek() every loop, change it to char = myStack.Peek() however I get weird lettering when that happens.

CodePudding user response:

since you already got the string with letters you can basically reverse it and that's it.

//emplace version:
void reverse_str(std::string& in)
{
    std::reverse(in.begin(), in.end());
}

//copy version
std::string reverse_str(std::string in)
{
    std::reverse(in.begin(), in.end());
    return in;
}

in your case the emplace version would be the best match. in other cases (e.g. when you want to preserve the original string) the copy version is preferred.


adding an example to make it as clean as possible.

int main()
{
    std::string inputstr = "123abc";
    std::string numbers{};
    std::string letters{};
    
    
    for(auto c : inputstr)
    {
        if(isdigit(c))
            numbers  = c;
        else
            letters  = c;
    }
    
    reverse_str(letters); //using the emplace version
    std::cout << numbers   letters;
}

CodePudding user response:

Here's my take. It only loops through the string once. I don't have your types, so I'm just using the std versions.

std::string output;
output.reserve( myString.size() );

std::stack<char> stack;
for ( char c : myString ) {
   if ( std::isdigit( c ) )   // if it's a number, just add it to the output
       output.push_back( c );
   else  // otherwise, add the character to the stack
       stack.push( c );
}

// string is done being processed, so use the stack to get the
// other characters in reverse order
while ( !stack.empty() ) { 
    output.push_back( stack.top() );
    stack.pop();
}

std::cout << output;

working example: https://godbolt.org/z/eMazcGsMf

Note: wasn't sure from your description how to handle characters other than letters and numbers, so treated them the same as letters.

CodePudding user response:

One way to do this is as follows:

Version 1

#include <iostream>
#include <string>

int main() {
 std::string s = "abc123";
    
    std::string output;
    output.resize(s.size());
    
   int i = output.length() - 1;
    int j = 0;
    
    for(char &c: s)
    {
        if(!std::isdigit(c))
           {
            
            output.at(i) = c;
            
            --i;
           }
        else
        {
           
           
            output.at(j) = c;
              j;
        }
    }
    
    std::cout<<output<<std::endl;
    
    
}

You can also use iterators in the above program to obtain the desired result as shown in version 2.

Version 2

#include <iostream>
#include <string>

int main() {
 std::string s = "abfsc13423";
    
    std::string output;
    output.resize(s.size());
    
   
    std::string::reverse_iterator iter = output.rbegin();
    std::string::iterator begin = output.begin();
   
    
    for(char &c: s)
    {
        if(!std::isdigit(c))
           {
            
            *iter = c;
            
            
              iter;
            
           }
        else
        {
            
            *begin = c;
            
               begin;
           
        }
    }
    
    std::cout<<output<<std::endl;
    
    
}
  • Related