C++ reversing a string with only one string - c++

I am trying to reversing a string with only using one string, but when I output the string it is missing a letter. Is something being over written that I do not know about? Here is my code:
#include <iostream>
using namespace std;
int main() {
string d = "jakejosh"; //11
char temp = '\0';
int j = d.size()/2;
for (int i=d.size()/2; i> 0; i--) //5
{
temp = d[i+j];
d[j+i] = d[j-i];
d[j-i] = temp;
}
cout << d << endl;
return 0;
}
Output is: ttam olle
Output should be: ttam olleh

When the size of a string is even then the code is wrong. For example if the size is equal to 2 then size() / 2 is equal to 1 and in the loop you will get thet d[i+j] is equivalent to d[size() / 2 + size() / 2] that is equal to d[2] while the valid range of indices is [0,1]
Also you should include header <string> and you could use standard function std::swap
The simplest approach is the following
#include <iostream>
#include <string>
int main()
{
std::string s = "hello matt";
s = std::string( s.rbegin(), s.rend() );
std::cout << s << std::endl;
return 0;
}
If you want to write the loop yourself then the code can look like
#include <iostream>
#include <string>
int main()
{
std::string s = "hello matt";
for ( std::string::size_type i = 0; i < s.size() / 2; i++ )
{
char c = s[i];
s[i] = s[s.size()-i-1];
s[s.size()-i-1] = s[i];
}
std::cout << s << std::endl;
return 0;
}
Or you can write some exotic solution.:) For example
#include <iostream>
#include <string>
#include <utility>
int main()
{
std:: string s = "Jake Smith";
std::cout << s << std::endl;
for ( std::string::size_type i = 0, j = s.size(); j - i > 1; i++ )
{
std::swap( s[i], s[--j] );
}
std::cout << s << std::endl;
return 0;
}
The program output is
Jake Smith
htimS ekaJ
Or you can try to write a recursive function.
At last you could use standard algorithm std::reverse declared in header <algorithm>.

Use std::reverse() to do that. For educational purposes take a look at the following pure C algorithms: http://www.programmingsimplified.com/c-program-reverse-string

for (int i=d.size()/2; i> 0; i--) //5
{
temp = d[i+j-1]; // d[9] i.e.must be 9 not 10 for swapping with 'h'
d[j+i-1] = d[j-i];
d[j-i] = temp;
}

It's very easy to trip up with indices when reversing a string in place.
If your string is of length LEN, then the valid indices are 0 - N-1.
In your case, let's take a look at the middle and how you start swapping from there.
hello matt
For reversing the string, you'll have to swap
hello matt (swap 0-th and 9-th)
^ ^
hello matt (swap 1-st and 8-th)
^ ^
hello matt (swap 2-nd and 7-th)
^ ^
hello matt (swap 3-rd and 6-th)
^ ^
hello matt (swap 4-th and 5-th)
^^
The start value for i is (N-1)/2.
The end vale for i is 0.
The index for swapping the value at i is len - 1 - i. (swap d[0] with d[9] in your case)
Putting that all together, the function should be something like:
void reverse_string(string& d)
{
int len = d.length();
for (int i=(len-1)/2; i >= 0; i--)
{
int j = len - 1 - i;
char temp = d[j];
d[j] = d[i];
d[i] = temp;
}
}
Here's the main function to test it.
int main()
{
string d = "hello matt";
reverse_string(d);
cout << d << endl;
d = "hello max";
reverse_string(d);
cout << d << endl;
return 0;
}

Related

C++ terminate called after throwing an instance of 'std::invalid_argument'

I just wrote this program. The test case I am using is 541. It is supposed to reverse the 541 into 154, then subtract 541 and 154, to get 396 then reverse that into 693. After that it is supposed to add 396 and 693 to get 1089. In the last three lines of code, I am trying to convert the strings into ints so I can add the last two numbers but I am getting this error. The code has to be done in this specific way for my class.
#include <iostream>
#include <string>
#include <algorithm>
/**
* main application starting point
* #return integer (0=SUCCESS)
*/
int main() {
//prompts user to input a three-digit number
std::string threeDigitNum;
std::cout << "Enter a 3-digit number, where the first and last digit differ by at least one" ;
std::cin >> threeDigitNum;
//uses a for loop to output the reverse of the first number
std::string threeReversed;
int control = 0;
for(int i = 2; i >= 0; i--){
threeReversed[control] = threeDigitNum[i];
control++;
}
std::cout << threeDigitNum[2]+ threeDigitNum[1]+ threeDigitNum[0] << std::endl;
//converts the numbers in the strings to integers
//displays the differnce of the first and second number
int firstNum = std::stoi(threeDigitNum);
int secondNum = std::stoi(threeReversed);
std::cout << firstNum - secondNum << std::endl;
std::string thirdNum;
thirdNum = std::to_string(firstNum - secondNum);
std::string thirdNumReverse;
for(int i = thirdNum.length(); i >= 0; i--){
thirdNumReverse = thirdNumReverse + thirdNum[i];
}
std::cout << thirdNumReverse << std::endl;
int fourthNum = std::stoi(thirdNum);
int fifthNum = std::stoi(thirdNumReverse);
std::cout<< fourthNum + fifthNum;
return 0;
}
Here's a hint:
std::string thirdNumReverse;
for(int i = thirdNum.length(); i >= 0; i--){
thirdNumReverse = thirdNumReverse + thirdNum[i];
}
If the length of thirdNum is 3, then the valid indices are from [2..0]. But yor code enumerates a different range of indices.
You are creating an empty string
std::string threeReversed;
and then you try to write into that empty (!) string using the subscript operator (using positions which don't exist in that string).
threeReversed[control] = threeDigitNum[i];
If you want to reverse a string, you can use a C++ Standard Library algorithm:
std::string threeReversed{ threeDigitNum };
std::reverse(threeReversed.begin(), threeReversed.end());
Later in the code, you have the same issue again for thirdNumReverse.
You are at a point where you want to learn how to debug small programs.
You may also want to use smaller methods which you can test on their own. See how short your code can become when you use a method that does the number reversing process for you:
#include <iostream>
#include <string>
#include <algorithm>
#include <cassert>
int reverse(int i)
{
std::string s = std::to_string(i);
std::reverse(s.begin(), s.end());
return std::stoi(s);
}
int main() {
assert(reverse(541) == 145);
int threeDigitNum{541};
int threeReversed = reverse(threeDigitNum);
std::cout << threeReversed << std::endl;
std::cout << threeDigitNum - threeReversed << std::endl;
int thirdNum = threeDigitNum - threeReversed;
int thirdNumReverse = reverse(thirdNum);
std::cout << thirdNumReverse << std::endl;
std::cout << thirdNum + thirdNumReverse;
return 0;
}
There are 2 errors in your code :
Error 1 : Creating empty string, but accessing other indices.
std::string threeReversed;
int control = 0;
for(int i = 2; i >= 0; i--){
threeReversed[control] = threeDigitNum[i];
control++;
}
change above code as you already did while calculating thirdNumReverse :
std::string threeReversed;
for(int i = 2; i >= 0; i--){
threeReversed = threeReversed + threeDigitNum[i];
}
Error 2 : indices are 0 based in c++, so start from thirdNum.length() - 1 instead of thirdNum.length()
for(int i = thirdNum.length(); i >= 0; i--){
thirdNumReverse = thirdNumReverse + thirdNum[i];
}
change above code as below :
for(int i = thirdNum.length() - 1; i >= 0; i--){
thirdNumReverse = thirdNumReverse + thirdNum[i];
}
Note : This code can be improved but I am just pointing out the errors in your existing code. Not improving it.

How to convert an integer to an array of its digits in C++

Suppose I have the integer 1004.
I want to store this in the array A with the following pattern:
A[0]=1
A[1]=0
A[2]=0
A[3]=4
How can I get the value at that index ?
How can I do this in C++?
You get the last index of a number by using modulo 10 and then remove that value by dividing the number by 10.
So assume you do this:
1004 % 10 = 4
1004 / 10 = 100
Then repeat that for each digit
Using c++ static memory:
int originalNumber = 1004;
int digitArray[10] = {0};
int idx = 0;
while (originalNumber > 0)
{
int digit = n % 10;
originalNumber /= 10;
digitArray[idx] = digit;
++idx;
}
// Reverse the order of the array
std::reverse(std::begin(digitArray), std::begin(digitArray)+(idx-1));
I'm not sure if it's the most efficient way of doing this but it definitely works.
You can enter each digit in the number to the array but from the end of the array to the beginning.
For example, there is an array with the size of 4, so you get the last digit of the number like this: num % 10, and push the digit to the third index of the array.
Code example:
#define SIZE 4
int* numToArray(int num)
{
int* arr = new int[SIZE]; // assuming you already know the number of digits in the number
for(int i = SIZE-1; i >= 0; i++)
{
arr[i] = num % 10; // Enters the last digit to the array
num /= 10; // Gets rid of the last digit in the number
}
return arr;
}
Instead of ordinary integer array, I suggest you using std::vector instead.
Then, you can have something like the following:
#include <iostream>
#include <vector>
int main() {
int number = 1004;
std::vector<int> digits;
while (number != 0) {
digits.insert(digits.begin(), number % 10);
number /= 10;
}
for (auto const i : digits) {
std::cout << i << " "; // 1 0 0 4
}
// or by index
std::cout << std::endl;
std::cout << "[0]" << digits[0] << std::endl; // 1
std::cout << "[1]" << digits[1] << std::endl; // 0
std::cout << "[2]" << digits[2] << std::endl; // 0
std::cout << "[3]" << digits[3] << std::endl; // 4
return 0;
}
Demo
Adding to all the existing answers I'd like to propose a more elegant, if probably less efficient approach utilizing the many wonders of the standard library.
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
auto number = 1004;
auto asString = std::to_string(number); //
std::vector<int> digits(asString.length());
std::transform(asString.begin(), asString.end(), digits.begin(), [](char c){return c -'0';});
for(auto d : digits)
{
std::cout << d << ' ';
}
}

Combination of unique elements without repetition

Elements : a b c
all combinations in such a way:abcabacbcabc
Formula to get total number of combinations of unique elements without repetition = 2^n - 1 (where n is the number of unique elements)
In our case top: 2^3 - 1 = 7
Another formula to get the combinations with specific length = n!/(r! * (n - r)!) (where n= nb of unique items and r=length)
Example for our the above case with r=2 : 3!/(2! * 1!) = 3 which is ab ac bc
Is there any algorithm or function that gets all of the 7 combinations?
I searched a lot but all i can find is one that gets the combinations with specific length only.
UPDATE:
This is what I have so far but it only gets combination with specific length:
void recur(string arr[], string out, int i, int n, int k, bool &flag)
{
flag = 1;
// invalid input
if (k > n)
return;
// base case: combination size is k
if (k == 0) {
flag = 0;
cout << out << endl;
return;
}
// start from next index till last index
for (int j = i; j < n; j++)
{
recur(arr, out + " " + arr[j], j + 1, n, k - 1,flag);
}
}
The best algorithm I've ever find to resolve this problem is to use bitwise operator. You simply need to start counting in binary. 1's in binary number means that you have to show number.
e.g.
in case of string "abc"
number , binary , string
1 , 001 , c
2 , 010 , b
3 , 011 , bc
4 , 100 , a
5 , 101 , ac
6 , 110 , ab
7 , 111 , abc
This is the best solution I've ever find. you can do it simply with loop. there will not be any memory issue.
here is the code
#include <iostream>
#include <string>
#include <math.h>
#include<stdio.h>
#include <cmath>
using namespace std;
int main()
{
string s("abcd");
int condition = pow(2, s.size());
for( int i = 1 ; i < condition ; i++){
int temp = i;
for(int j = 0 ; j < s.size() ; j++){
if (temp & 1){ // this condition will always give you the most right bit of temp.
cout << s[j];
}
temp = temp >> 1; //this statement shifts temp to the right by 1 bit.
}
cout<<endl;
}
return 0;
}
Do a simple exhaustive search.
#include <iostream>
#include <string>
using namespace std;
void exhaustiveSearch(const string& s, int i, string t = "")
{
if (i == s.size())
cout << t << endl;
else
{
exhaustiveSearch(s, i + 1, t);
exhaustiveSearch(s, i + 1, t + s[i]);
}
}
int main()
{
string s("abc");
exhaustiveSearch(s, 0);
}
Complexity: O(2^n)
Here's an answer using recursion, which will take any number of elements as strings:
#include <vector>
#include <string>
#include <iostream>
void make_combos(const std::string& start,
const std::vector<std::string>& input,
std::vector<std::string>& output)
{
for(size_t i = 0; i < input.size(); ++i)
{
auto new_string = start + input[i];
output.push_back(new_string);
if (i + 1 == input.size()) break;
std::vector<std::string> new_input(input.begin() + 1 + i, input.end());
make_combos(new_string, new_input, output);
}
}
Now you can do:
int main()
{
std::string s {};
std::vector<std::string> output {};
std::vector<std::string> input {"a", "b", "c"};
make_combos(s, input, output);
for(auto i : output) std::cout << i << std::endl;
std::cout << "There are " << output.size()
<< " unique combinations for this input." << std::endl;
return 0;
}
This outputs:
a
ab
abc
ac
b
bc
c
There are 7 unique combinations for this input.

Is this a good way to break out of the while loop if there is not substring?

I'm working on this small code. It is giving the right output but I think the loop that I have on it could be improved.
Question 1: Given a string A consisting of n characters, and a string B consisting of m characters, write a function that will return the number of times A must be stated such that B is a substring of the repeated A. If B can never be a substring, return -1.
Example:
A = "abcd"
B = "cdabcdab"
The function should return 3 because after stating A 3 times, getting "abcdabcdabcd", B is now a substring of A.
You can assume that n and m are integers in the range [1, 1000].
This is my code:
#include "pch.h"
#include <iostream>
#include <string>
#include <fstream>
#include <istream>
using namespace std;
int findthestring(string A, string B)
{
string original = B;
int times = 1 ;
if (B.find(A) != string::npos)
{
cout << "String Found\n";
times =1;
}
for (unsigned int i = 0; i < (10 * A.length());i++)
{
cout << "String not Found\n";
B = B + original;
times = times + 1;
if (times>10)
{
return -1;
break;
}
}
return times;
}
int main()
{
int times = findthestring("cdabcdab","abcd");
cout << "Number of Times: " << times;
return 0;
}
On this code, I have the loop run for 10 times, if there is no sub string, then the loop breaks out and returns 1.
Is there a better way to do that?
You could use recursively the method string::find(const std::string& str, size_t pos = 0) while its returned value would be equal to std::string::npos:
#include <iostream>
#include <string>
int findthestring(const std::string& substr, const std::string& str)
{
size_t times = 1;
std::string temp(substr);
while (temp.find(str) == std::string::npos) { // while not found
times++;
if (times > 10) {
return -1;
}
temp += substr; // concatenate string
}
return times;
}
int main()
{
int times = findthestring("abcd", "cdabc");
std::cout << "Number of Times: " << times;
return 0;
}

producing all anagrams in a string c++

I saw this problem online, and I was trying to solve it in C++. I have the following algorithm:
char permutations( const char* word ){
int size = strlen( word );
if( size <= 1 ){
return word;
}
else{
string output = word[ 0 ];
for( int i = 0; i < size; i++ ){
output += permutations( word );
cout << output << endl;
output = word[ i ];
}
}
return "";
}
For example, if I have abc as my input, I want to display abc, acb, bac, bca, cab, cba.
So, what I'm trying to do is
'abc' => 'a' + 'bc' => 'a' + 'b' + 'c'
=> 'a' + 'c' + 'b'
so I need o pass a word less char every function call.
Could someone please help how to do it?
I suggest doing it using the algorithm header library in C++, much easier; and as a function can be written like this:
void anagram(string input){
sort(input.begin(), input.end());
do
cout << input << endl;
while(next_permutation(input.begin(), input.end()));
}
However since you want it without the STL, you can do it like so:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap (char *x, char *y)
{
char ch = *x;
*x = *y;
*y = ch;
};
void permutate_(char* str, size_t index )
{
size_t i = 0;
size_t slen = strlen(str);
char lastChar = 0;
if (index == slen )
{
puts(str);
return;
}
for (i = index; i < slen; i++ )
{
if (lastChar == str[i])
continue;
else
lastChar = str[i];
swap(str+index, str+i);
permutate_(str, index + 1);
swap(str+index, str+i);
}
}
// pretty lame, but effective, comparitor for determining winner
static int cmpch(const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}
// loader for real permutor
void permutate(char* str)
{
qsort(str, strlen(str), sizeof(str[0]), cmpch);
permutate_(str, 0);
}
Which you can call by sending it a sorted array of characters,
permutate("Hello World");
The non-STL approach was gotten from here.
The STL is wonderful:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void permutations(const char *word) {
string s = word;
sort(s.begin(), s.end());
cout << s << endl;
while(next_permutation(s.begin(), s.end()))
cout << s << endl;
}
int main() {
permutations("abc");
return 0;
}
Now, next_permutation can be implemented quite simply. From the end of the string, iterate backwards until you find an element x which is less than the next element. Swap x with the next value larger than x in the remainder of the string, and reverse the elements coming afterwards. So, abcd becomes abdc since c < d; cdba becomes dabc since c < d and we flip the last three letters of dcba; bdca becomes cabd because b < d and we swap b for c.