Remove additional spaces C++ - c++

I have the homework assignment where I should remove all leading spaces in the char array. If there is a space in the beginning of the array, it should be deleted too. Also, I have to take care about an empty array. I can't use <cstring> and <string.h>. Also, I can't create any additional arrays. I googled a lot, but I have no idea how to solve this problem. Here is what I have so far.
void clean(char* tab)
{
//char *p = tab;
for (int i = 0; i <= sizeof(tab); i++)
{
if ((tab[i] = ' ') && (tab[i + 1] = ' '))
{
tab[i] = tab[i + 1];
}
}
}
int main()
{
char tab1[] = " h qa w e ";
cout << tab1 << endl;
clean(tab1);
cout << tab1 << endl;
}
Will be very gratefull if someone can give me a hint how to figure it out.

Regard each space as a "free space" in the array, one which you should fill.
You can maintain two pointers to different places in your char array. One to the first available space, another to the currently character you examine.
You only need to figure out these questions:
How would you fill up the spaces?
How would you know when you're done?

You have a few separate problems here.
One is that you've mis-typed your comparisons: if ((tab[i] = ' ') && (tab[i+1] = ' ')) should undoubtedly be: if ((tab[i] == ' ') && (tab[i+1] == ' ')).
Second, you're using sizeof(a pointer), where you really wanted strlen(a pointer) (or at least something that works similarly, scanning for a NUL character that signals the end of the string).
Third, the algorithm your loop implements doesn't seem to reflect the intent of removing leading spaces very well (if at all). I'd scan for the first thing that wasn't a space, then copy the remainder of the string so it starts at the beginning of the string.
[Sorry, but I'm not going to post actual code or much more detail than that for a homework assignment.]

Those codes work with absolutely no dependency on nor and they don't allocate any temporary buffers. Note that a home made copy function must be defined to copy string content when a space is being removed.
Note that this code is easy to understand but may/should be optimized to minimize copies if performance is a requirement.
As it's unclear what you exactly want...
This one removes all spaces in the string.
#include <iostream>
void copy( char* to, char* from )
{
int i = 0;
while ( true ) // risky in case char* has no EOS character!
{
to[i] = from[i];
if ( from[i] != '\0' )
++i;
else
break;
}
}
void clean( char* tab )
{
int i = 0;
while ( tab[i] != '\0' )
{
if ( tab[i] == ' ')
{
copy( tab + i, tab + i + 1 );
// do not increment i, to test tab[i] that was newly copied from tab[i+1]
}
else
{
++i;
}
}
}
int main() {
char tab1[] = " h qa w e ";
std::cout << tab1 << std::endl;
clean(tab1);
std::cout << tab1 << std::endl;
}
https://ideone.com/Yv4aqL
If you only want to remove leading spaces, it's even easier, just change the clean function:
void clean( char* tab )
{
int i = 0;
while ( tab[i] == ' ' )
{
copy( tab + i, tab + i + 1 );
}
}
https://ideone.com/RIAsGt

Related

Remove out excess spaces from string in C++

I have written program for removing excess spaces from string.
#include <iostream>
#include <string>
void RemoveExcessSpaces(std::string &s) {
for (int i = 0; i < s.length(); i++) {
while (s[i] == ' ')s.erase(s.begin() + i);
while (s[i] != ' ' && i < s.length())i++;
}
if (s[s.length() - 1] == ' ')s.pop_back();
}
int main() {
std::string s(" this is string ");
RemoveExcessSpaces(s);
std::cout << "\"" << s << "\"";
return 0;
}
One thing is not clear to me. This while (s[i] == ' ')s.erase(s.begin() + i); should remove every space in string, so the output would be thisisstring, but I got correct output which is this is string.
Could you explain me why program didn't remove one space between this and is and why I got the correct output?
Note: I cannot use auxiliary strings.
That is because when your last while loop finds the space between your characters (this is) control pass to increment part of your for loop which will increase the value of int i then it will point to next character of given string that is i(this is string) that's why there is space between (this is).
Your second while loop will break when s[i]==' '. But then your for loop will increment i and s[i] for that i will be skipped. This will happen for every first space character after each word.

How to find a sequence of letter in a given string?

My string is "AAABBAABABB",
and I want to get the result as
A = 3
B = 2
A = 2
B = 1
A = 1
B = 2
I have tried to use
for (int i = 0; i < n - 1; i++) {
if (msg[i] == msg[i + 1]) {
if(msg[i]==A)
a++;
else
b++;
}
}
I tried this by it didn't work for me. And I don't understand if there any other ways to find it out. Please help me out.
Iterate through the array by followings:
If i = 0, we can set a variable as 0th character and counter by 1.
If ith character is equal to the previous character, we can increase the counter.
If ith character is not equal to the (i-1)th character we can print the character, counter and start counting the new character.
Try the following snippet:
char ch = msg[0];
int cnt = 1;
for (int i = 1; i < n; i ++){
if(msg[i] != msg[i-1]){
cout<<ch<<" "<<cnt<<endl;
cnt = 1;
ch = msg[i];
}
else {
cnt++;
}
}
cout<<ch<<" "<<cnt<<endl;
You can use std::vector<std::pair<char, std::size_t>> to store character occurrences.
Eventually, you would have something like:
#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main() {
std::vector<std::pair<char, std::size_t>> occurrences;
std::string str{ "AAABBAABABB" };
for (auto const c : str) {
if (!occurrences.empty() && occurrences.back().first == c) {
occurrences.back().second++;
} else {
occurrences.emplace_back(c, 1);
}
}
for (auto const& it : occurrences) {
std::cout << it.first << " " << it.second << std::endl;
}
return 0;
}
It will output:
A 3
B 2
A 2
B 1
A 1
B 2
Demo
This is very similar to run length encoding. I think the simplest way (less line of codes) I can think of is like this:
void runLength(const char* msg) {
const char *p = msg;
while (p && *p) {
const char *start = p++; // start of a run
while (*p == *start) p++; // move p to next run (different run)
std::cout << *start << " = " << (p - start) << std::endl;
}
}
Please note that:
This function does not need to know the length of input string before hand, it will stop at the end of string, the '\0'.
It also works for empty string and NULL. Both these work: runLength(""); runLength(nullptr);
I can not comment yet, if you look carefully, mahbubcseju's code does not work for empty msg.
With std, you might do:
void print_sequence(const std::string& s)
{
auto it = s.begin();
while (it != s.end()) {
auto next = std::adjacent_find(it, s.end(), std::not_equal_to<>{});
next = next == s.end() ? s.end() : next + 1;
std::cout << *it << " = " << std::distance(it, next) << std::endl;
it = next;
}
}
Demo
Welcome to stackoverflow. Oooh, an algorithm problem? I'll add a recursive example:
#include <iostream>
void countingThing( const std::string &input, size_t index = 1, size_t count = 1 ) {
if( input.size() == 0 ) return;
if( input[index] != input[index - 1] ) {
std::cout << input[index - 1] << " = " << count << std::endl;
count = 0;
}
if( index < input.size() ) return countingThing( input, index + 1, count + 1 );
}
int main() {
countingThing( "AAABBAABABB" );
return 0;
}
To help work out algorithms and figuring out what to write in your code, I suggest a few steps:
First, write out your problem in multiple ways, what sort of input it expects and how you would like the output to be.
Secondly, try and solve it on paper, how the logic would work - a good tip to this is try to understand how YOU would solve it. Your brain is a good problem solver, and if you can listen to what it does, you can turn it into code (it isn't always the most efficient, though).
Thirdly, work it out on paper, see if your solution does what you expect it to do by following your steps by hand. Then you can translate the solution to code, knowing exactly what you need to write.

Replacing all spaces in a string with '%20' (C++)

Having some trouble understanding parts of the code; the output I am getting is also wrong. The problem is to replace all spaces in a string with '%20'. The full code is shown below; it compiles but doesn't run exactly as it should.
#include <iostream>
#include <string>
using namespace std;
void replaceSpaces(string str){
//Getting the length of the string, counting the number of spaces
int strLen = str.length();
int i, count = 0;
for (i = 0; i <= strLen; i++) {
if(str[i]==' ')
count++;
}
//Determining the new length needed to allocate for replacement characters '%20'
int newLength = strLen + count * 2;
str[newLength] = '\0';
for (i = strLen - 1; i >= 0; i--) {
if (str[i] == ' ') {
str[newLength - 1] = '0';
str[newLength - 2] = '2';
str[newLength - 3] = '%';
newLength = newLength - 3;
}
else {
str[newLength - 1] = str[i];
newLength = newLength -1;
}
}
cout << str <<endl;
}
int main() {
string str = "hello jellybean hello";
replaceSpaces(str);
return 0;
}
I am probably missing something obvious, but when allocating for the new string length in this line:
int newLength = strLen + count * 2;
Here we are multiplying the number of spaces by 2, but if we are trying to replace all spaces with '%20', why not multiply it by 3?
str[newLength] = '\0';
Does this line indicate that the position past the last character in the string is assigned a null space?
Am also confused about the else statement.
else {
str[newLength - 1] = str[i];
newLength = newLength -1;
}
Not sure if I completely understand the circumstance when this would be executed.
When the functions are compiled and run, if
string str = "hello jellybean hello";
the expected output would be hello%20jellybean%20hello, except the output I am getting is hello%20jellybean%20h.
In terms of time complexity, since there are two independent for loops, would the time complexity be O(n)?
I know I'm asking a lot of different questions, many thanks in advance for any answers!
This is wrong:
str[newLength] = '\0';
std::string objects maintain their NUL terminator internally based on their size. You want
str.resize(newLength);
instead.
int newLength = strLen + count * 2;
says to allocate space (later), equal to the length of the string, plus the number of whitespaces found multiplied by two, which makes sense.
For example: so glad to help, should use the slots that the whitespaces live into for the % and they will need two more slots each, for the 20 part of the replacement that will come into play.
This is WRONG:
str[newLength] = '\0';
can't you see? You access memory out of the bounds of your string. You act like you actually allocated space equal to the newLength, but you haven't that anywhere in the code yet.
Out of bounds accessing result in Undefined Behavior and that's bad.
The else statement is just for copying non-whitespace characters, but you should already given up on that code (if it's not yours) and start from scratch or/and take a sneak peak at: Encode/Decode URLs in C++.
As for the wrong result, you should know by reaching that point of that answer, that this is expected.
Trying to do the modification in place is tricky. It's much easier to create a new string:
std::string new_string;
for (int i = 0; i < str.length(); ++i) {
if (str[i] == ' ')
new_string += "%20";
else
new_string += str[i];
}
return new_string;
or, if you like range-for:
std::string new_string;
for (char ch : str) {
if (ch == ' ')
new_string += "%20";
else
new_string += ch;
}
return new_string;
You can change that string argument in function to reference, then there wont be any need for new string, at other part of the code, you can use insert function to add '2' and '0', and you only need to convert space to '&'.
void replaceSpaces(string &str) {
size_t strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (str[i] == ' ') {
str[i] = '%';
str.insert(str.begin() + i + 1, '2');
str.insert(str.begin() + i + 2, '0');
strLen += 2;
}
}
}
This is easy; replace examplestring with your string in the code, and use as you would:
#include <iostream> //debug output
#include <string>
using std::string;
using std::cout;
using std::endl;
//the string to convert
string examplestring = "this is the example string for spaces into %20";
int main()
{
int countspaces = 0; //its faster to fill a known size
for (auto &x : examplestring)if (x == ' ')countspaces++; //counts spaces
string newstring; //declare new string
newstring.resize(examplestring.size() + (countspaces*3)); //pre-set size to make it run faster
int newstringiterator = 0; //keep track of new string location
//if ' '(space), place %20 in newstring and add 3 to iteration
//else just place the letter and iterate
for (int i=0;i<examplestring.size();i++)
{
if (examplestring[i] == ' ')
{
newstring.insert(newstringiterator, "%20");
newstringiterator += 3;
}
else newstring[newstringiterator++] = examplestring[i];
}
//final newstring is the original with %20 instead of spaces.
cout << newstring << endl;
system("PAUSE"); //to read console output
return 0; //return to zero
}
This will output newstring, which is the old string with '%20' instead of spaces.

C++ need help figuring out word count in function. (Ex. Hello World = 2)

I'm figuring out the algorithm on this function and it keeps crashing at runtime, here's the code snippet:
int wordCounter(char usStr[]) {
int index= 0, punct= 0;
while(usStr[index]!= '\0') //If it's not the end of the sentence
if(usStr[index]== ' ') //If it finds a space
index++;
while(usStr[index]== '\0') //If it's the end of the sentence.
punct++;
int allChar= punct+ index;
return allChar;
}
I shall post the full program if need arises, but for now I need someone to help me crack down the source of the problem.
UPDATE: Here's my int main. Assume numWords is a function that accepts a string class object as its argument and asks the user for input:
int main()
{
string userVal;
numWords(userVal);
char *conStr= new char[' ']; //I'm very doubtful and worried about the contents insing the [].
strcpy(conStr, userVal.c_str()); //String converted to a C-string.
int fin= wordCounter(conStr);
cout<< "The number of words in the sentence is "<< fin<< "."<< endl;
pause();
return 0;
}
Though I have no idea what you're really asking for, I think you should have a condition to end your 1st while() loop to adjust at beginning of words:
int wordCounter(char usStr[]) {
int index= 0, punct= 0;
while(usStr[index]!= '\0') { // <<< Use effin' braces
if(usStr[index]== ' ') { // <<< Use effin' braces
index++;
}
else {
break;
}
}
// index points to a non ' ' character or '\0' here
// No idea, what you're trying to achieve with the following lines
// of code.
while(usStr[index] == '\0') { // If it's the end of the sentence ...
// ... this part loops forever!
punct++;
}
int allChar = punct + index;
return allChar;
}
Simple array way:
int wordCounter(char usStr[])
{
int wordcount = 0;
int charcount = 0;
int index = 0;
while (usStr[index] != '\0')
{
if (usStr[index] == ' ')
{
if (charcount)
{ //only count non-empty tokens
wordcount++;
charcount = 0;
}
}
else
{
charcount++;
}
index++;
}
if (charcount)
{ // get last word, if any.
wordcount++;
}
return wordcount;
}
Simple C++ way:
int wordCounter(char usStr[])
{
int wordcount = 0;
std::stringstream stream(usStr);
std::string temp;
while (stream >> temp)
{ // got a token
wordcount++;
}
return wordcount;
}
Breakdown of what went wrong:
while(usStr[index]!= '\0') //good
if(usStr[index]== ' ') //good
index++; //bad
Lets look at a simple case "Hi!"
Iteration 1:
index = 0, usStr[index] = H
while(usStr[index]!= '\0')
H != '\0', enter
if(usStr[index]== ' ') //good
H != ' ', do not enter. Do not increment index
Iteration 2:
index = 0, usStr[index] = H
while(usStr[index]!= '\0')
H != '\0', enter
if(usStr[index]== ' ') //good
H != ' ', do not enter. Do not increment index
Iteration 3:
index = 0, usStr[index] = H
while(usStr[index]!= '\0')
H != '\0', enter
if(usStr[index]== ' ') //good
H != ' ', do not enter. Do not increment index
See the problem yet? If not, I can cut and past all night. Rather get some food and sleep, though.
int wordCounter(char usStr[]) {
int index= sizeof(usStr);
int result = 0;
for (int i=0; i<index; i++){
if(usStr[index]== ' ')
result++;
}//end of the loop
return result+1;
} //try this one.
Be warned, I'm a beginner. Sorry, I feel like I have to say that in case I'm totally wrong. :) Hopefully I won't have to say that for too long.
Anyways, I would do this in the simplest way I can come up with. Instead of a char array, I would just use a std::string. Here's a little function I made, which is derived from a function I made to split std::strings into substrings.
// split the string s into substrings and count the number of substrings
int count_substrings(const string& s)
{
int count{ 0 };
stringstream ss{ s };
for (string buffer; ss >> buffer;)
++count;
return count;
}
So what this does is it takes the string and stores it into a stringstream. Then the "ss >> buffer" will go through the characters in the string and when it hits whitespace, it'll store that substring into "buffer" and go into the for loop, which increments "count". It goes into the for loop each time it finds a substring, which is how it counts the number of substrings. Notice that "buffer" isn't actually being used anywhere. I'm sorry if this is a bad explanation of what's going on, but I'm trying. :) I hope this can help you a bit to understand what I'm doing. Please, if I'm wrong about something, correct me.
Then a very simple test of this function could be something like this:
cout << "Enter a string:\n";
string str;
getline(cin, str);
int count = count_substrings(str);
cout << "Number of substrings == " << count << '\n';

how do i sort words into a structure array in C++?

I am very new to C++ so go easy on the words that I may or may not understand...
we are given a paragraph in string form and we are supposed to grab each word from the string and populate an array, and display the array. We learned about structures today so thats why we are supposed to output the docWordCount(and also why something is probably wrong with it....)
What I am trying to do is to move along the string until I find a space, and when I do I use the .substr command to copy the word into the array. I originally tried to use static_cast to find if there was a space or not, I Am not sure if the problem was that it doesnt work like that, or I did something wrong(probably latter). Everytime I would move along the string, I would increase the word count by 1, so it would output all of the word instead of whats infront of it. Also I should mention that when I compile the code, it outputs the text and then it gives me a "Debug assertion failed! [...] expression: string subscript out of range." error in another window.
#include <string>
#include <iostream>
using namespace std;
int main()
{
struct wordCount
{
string word;
int count;
};
wordCount docWordCount [500];
for(int i = 0; i < 500; i++)
{
docWordCount[i].word = "";
docWordCount[i].count = 0;
}
string text ="If there's one good thing that's come out of the European debt crisis\
it's that the U.S. has been able to shield itself from much of \
the mess. The sentiment will continue in 2012 as the U.S. \
economy is expected to grow faster than its European counterparts. \
That's according to the Organization for Economic Cooperation and \
Development which says the U.S. economy will expand at a 2.9% \
annual rate in the first quarter and then a 2.8% rate in the second quarter.";
cout << text << endl;
int wordLength = 0;
for(int i = 0; i < 500; i++)
{
if (text[i] == ' ' ) //if there isnt a space
wordLength++;
if (text[i] == !' ' ) //if there is a space
docWordCount[i].word = text.substr(i - wordLength, i);
}
for (int i = 0; i < 100; i++)
cout << docWordCount[i].word << endl;
return 0;
}
What it should look like is
If
Theres
one
good
thing
etc... is what I am trying to do sound? Is there an easier way to solve this?
A few errors, but otherwise sound.
You confuse the index to the text with the index into the word array; create a new variable wordIndex for the latter.
The operators for checking a space or not are wrong. == means is, use != for is not.
You should iterate i for text.length()
Better to change the 500 hard code to a constant.
Critically, you want text.substr(i - wordLength, wordLength); i.e. the second parameter is the length, not the end index of the substring.
Your code contains several bugs. For example this statement
if (text[i] == !' ' ) //if there is a space
is invalid. It compares character text[i] with boolean value false ( !' ' )
Try the following code (without testing). Maybe it contains less bugs than your code.:)
#include <string>
#include <iostream>
int main()
{
struct wordCount
{
std::string word;
int count;
};
const size_t N = 500;
wordCount docWordCount[N] = {};
std::string text ="If there's one good thing that's come out of the European debt crisis\
it's that the U.S. has been able to shield itself from much of \
the mess. The sentiment will continue in 2012 as the U.S. \
economy is expected to grow faster than its European counterparts. \
That's according to the Organization for Economic Cooperation and \
Development which says the U.S. economy will expand at a 2.9% \
annual rate in the first quarter and then a 2.8% rate in the second quarter.";
std::cout << text << std::endl;
size_t n = 0;
std::string::size_type i = 0;
while ( n < N && i < text.size() )
{
while ( i < text.size() && text[i] == ' ' ) ++i;
std::string::size_type j = i;
while ( i < text.size() && text[i] != ' ' ) ++i;
if ( j != i ) docWordCount[n++].word.assign( text, j, i - j );
}
for ( size_t i = 0; i < n; i++ ) std::cout << docWordCount[i].word << std::endl;
return 0;
}
It would be simpler if you would use member function of class std::string as for example find
By the way the name of the thread does not correspond to its description. There was said nothing about sort.