Assume that the value of a = 1, b = 2, c = 3, ... , z = 26. You are given a numeric string S. Write a program to return the list of all possible codes that can be generated from the given string.
For most of the cases this code works but it gives wrong output for inputs which have numbers greater than 26. For eg: 12345.
#include <iostream>
#include <string.h>
using namespace std;
using namespace std;
int atoi(char a)
{
int i=a-'0';
return i;
}
char itoa(int i)
{
char c='a'+i-1;
return c;
}
int getCodes(string input, string output[10000]) {
if(input.size()==0)
{
return 1;
}
if(input.size()==1)
{
output[0]=output[0]+itoa(atoi(input[0]));
return 1;
}
string result1[10000],result2[10000];
int size2;
int size1=getCodes(input.substr(1),result1);
if(input.size()>1)
{
if(atoi(input[0])*10+atoi(input[1])>10&&atoi(input[0])*10+atoi(input[1])<27)
{
size2=getCodes(input.substr(2),result2);
}
}
for(int i=0;i<size1;i++)
{
output[i]=itoa(atoi(input[0]))+result1[i];
}
for(int i=0;i<size2;i++)
{
output[i+size1]=itoa(atoi(input[0])*10+atoi(input[1]))+result2[i];
}
return size1+size2;
}
int main(){
string input;
cin >> input;
string output[10000];
int count = getCodes(input, output);
for(int i = 0; i < count && i < 10000; i++)
cout << output[i] << endl;
return 0;
}
if i give input 12345, the output is:
"
abcde
awde
lcde
l"
instead of :
"
abcde
awde
lcde"
i got it fellow members. i did not initialised the size2 variable to zero. also i didn't use >= operator.
int getCodes(string input, string output[10000]) {
if(input.size()==0)
{
output[0]="";
return 1;
}
if(input.size()==1)
{
output[0]=itoa(atoi(input[0]));
return 1;
}
string result1[10000],result2[10000];
int size2=0;
int size1=getCodes(input.substr(1),result1);
if(input.size()>1)
{
if(atoi(input[0])*10+atoi(input[1])>=10&&atoi(input[0])*10+atoi(input[1])<27)
{
size2=getCodes(input.substr(2),result2);
}
}
int k=0;
for(int i=0;i<size1;i++)
{
output[k++]=itoa(atoi(input[0]))+result1[i];
}
for(int i=0;i<size2;i++)
{
output[k++]=itoa(atoi(input[0])*10+atoi(input[1]))+result2[i];
}
return k;
}
this is the final code for getCodes function. Thanks everyone :)
You can do that more simply with something like this:
#include <utility>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
void getCodesRec(unsigned int num, string& current, vector<string>& result)
{
// First and last chars for the codes
static constexpr char FIRST_CHAR = 'a';
static constexpr char LAST_CHAR = 'z';
if (num == 0)
{
// When there is no more number add the code to the results
result.push_back(current);
}
else
{
// Add chars to the existing code
unsigned int next = num;
unsigned int rem = next % 10;
unsigned int f = 1;
// While we have not gone over the max char number
// (in practice this loop will run twice at most for a-z letters)
while (next > 0 && rem <= (unsigned int)(LAST_CHAR - FIRST_CHAR) + 1)
{
next = next / 10;
if (rem != 0) // 0 does not have a replacement
{
// Add the corresponding char
current.insert(0, 1, FIRST_CHAR + char(rem - 1));
// Recursive call
getCodesRec(next, current, result);
// Remove the char
current.erase(0, 1);
}
// Add another number
f *= 10;
rem += f * (next % 10);
}
}
}
vector<string> getCodes(unsigned int num)
{
vector<string> result;
string current;
getCodesRec(num, current, result);
return result;
}
int main()
{
unsigned int num = 12345;
vector<string> codes = getCodes(12345);
cout << "Codes for " << num << endl;
for (string& code : codes)
{
cout << "* " << code << endl;
}
return 0;
}
Output:
Codes for 12345
* abcde
* lcde
* awde
Related
I am writing a code that gets 2 inputs, one is a string and the other is an integer. It uses 2 overloaded functions to print the reverse of each input. What I want it to do is for the code to validate each input to see if it is a palindrome or not but I cannot seem to figure out a way to make the reverse variable a separate variable and compare it with the user input.
This is the code I have:
#include <iostream>
#include <ctime>
#include <time.h>
using namespace std;
void reverse(string s);
void reverse(int x);
int main() {
string str;
int x;
cout<<"Enter a string: "<< endl;
cin>> str;
reverse(str);
cout<<"Enter an integer: "<< endl;
cin>> x;
reverse(x);
return 0;
}
void reverse(string s){
int x = s.length();
for (int i = 0; i < x / 2; i++){
swap(s[i], s[x - i - 1]);
}
cout<<s<< endl;
}
void reverse(int x){
int reversedNumber = 0, remainder;
while(x != 0) {
remainder = x%10;
reversedNumber = reversedNumber*10 + remainder;
x /= 10;
}
cout << reversedNumber;
}
You can use reverse iterators to help you with this task (std::string::rbegin returns a reverse iterator that points to the end of the string). std::to_string allows you to convert you number to a string. There's no need to write your own function. Here is an example:
bool is_palindrome(const std::string &s)
{
return std::equal(s.begin(), s.begin() + s.size()/2, s.rbegin());
}
bool is_palindrome(const unsigned int i)
{
auto s = std::to_string(i);
return std::equal(s.begin(), s.begin() + s.size()/2, s.rbegin());
}
int main()
{
unsigned int number = 112343211;
std::string s = "abcdedcba";
std::cout << s << " is palindrome "
<< std::boolalpha << is_palindrome(s) << "\n";
std::cout << number << " is palindrome "
<< std::boolalpha << is_palindrome(number) << "\n";
}
Note that I have used unsigned ints for simplicity. If you want signed ints, you have to take care of the sign as well.
Demo.
Your existing functions print their result (by streaming to std::cout). To do anything more useful, you'll want to return the value.
For example:
std::string reverse(std::string s)
{
auto x = s.length();
for (std::size_t i = 0; i < x / 2; ++i) {
swap(s[i], s[x - i - 1]);
}
// Return the value for caller to use
return s;
}
Or more succinctly:
std::string reverse(const std::string& s)
{
return {s.rbegin(), s.rend()};
}
Then your main() can use tests such as
if (str == reverse(str))
Double the speed by reversing the last half of the input and checking it against the first half of the input.
Then decide whether checking char by char is faster than using a "reverse" function.
Perhaps something like this (plz excuse any syntax errors):
int len = s.length()
int mid = len / 2;
for (int i = 0; i < mid; i++){
if (s[i] != s[x - len - 1]) {
return false;
}
}
return true;
Then consider using pointers, which may be implemented better:
int len = s.length()
int mid = len / 2;
char *a = &s;
char *z = &s[len - 1];
for (int i = 0; i < mid; i++){
if (*a++ != *z--) {
return false;
}
}
return true;
(Is there a construct for "repeat N times?"; that would eliminate the need for an explicit i.)
Or maybe you can say while (a < z):
while (a++ < z--) {
if (*a != *z) {
return false;
}
}
return true;
I am trying to add large numbers using arrays without using bigint or anything like that. I can get my program to add the two arrays. However, I need to take the addition of the arrays and output the correct answer like a regular number. I cannot seem to make an algorithm to take the sum of my arrays and ouptut the answer. Does anybody have any tips or suggestions?
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>
#include <iterator>
using namespace std;
const int DIGITS = 20;
void readNum(int list[], int& length, string input1);
void reverseArray(int arr[], int start, int end);
void sumNum(int list1[], int numOfElementsList1,
int list2[], int numOfElementsList2);
int main()
{
// Write your main here
string input1;
string input2;
int list[DIGITS];
int list2[DIGITS];
int total[DIGITS];
int input1Length;
int input2Length;
cout << "Please enter your 1st number: " << endl;
cin >> input1;
cout << "Please enter your 2nd number: " << endl;
cin >> input2;
input1Length = input1.length();
input2Length = input2.length();
readNum(list, input1Length, input1);
readNum(list2, input2Length, input2);
reverseArray(list, 0, input1Length);
reverseArray(list2, 0, input2Length);
sumNum(list, input1Length, list2, input2Length);
}
void readNum(int list[], int& length, string input1)
{
int array[DIGITS];
for (int i = 0; i < length; i++)
{
array[i] = input1[i] - '0';
list[i] = array[i];
}
}
void reverseArray(int arr[], int start, int length)
{
int end;
end = length - 1;
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
void sumNum(int list1[], int numOfElementsList1,
int list2[], int numOfElementsList2)
{
int length;
int sum = 0;
int carry = 0;
int total[DIGITS];
if (numOfElementsList1 > numOfElementsList2)
{
length = numOfElementsList1;
}
else
{
length = numOfElementsList2;
}
for (int i = 0; i < length; i++)
{
sum = list1[i] + list2[i] + carry;
if (sum >= 10)
{
sum = sum % 10;
carry = 1;
}
else
{
carry = 0;
}
total[i] = sum;
cout << total[i];
}
}
Strings are arrays of characters, you could just use them as-is. The advantage being... they're just strings, and you can output them as a string just as easily. Not a new technique, it's called a binary coded decimal which in this case is a zoned BCD (where the zone is 0x30 in ASCII, or zone 0xF0 in EBCDIC).
#include <iostream>
#include <string>
#include <stdexcept>
using std::string;
using std::cout;
using std::cin;
using std::runtime_error;
static string sumNum(string, string);
int main() {
string input1;
string input2;
cout << "Please enter your 1st number: ";
cin >> input1;
cout << "Please enter your 2nd number: ";
cin >> input2;
auto sum = sumNum(input1, input2);
cout << "Sum is: " << sum << "\n";
}
string sumNum(string a, string b) {
//a = string(a.rbegin(), a.rend());
//b = string(b.rbegin(), b.rend());
string sum;
auto digit = [carry = 0](int value) mutable {
value += carry;
if (value > 9) {
carry = 1;
value -= 10;
} else {
carry = 0;
}
return static_cast<char>(value + '0');
};
auto num = [](char c) {
if (c < '0' || c > '9') {
throw runtime_error("not a digit");
}
return c - '0';
};
auto aa = a.rbegin();
auto bb = b.rbegin();
while(aa != a.rend() && bb != b.rend()) {
sum.push_back(digit((num(*aa)) + (num(*bb))));
++aa;
++bb;
}
while (aa != a.rend()) {
sum.push_back(digit(num(*aa)));
++aa;
}
while (bb != b.rend()) {
sum.push_back(digit(num(*bb)));
++bb;
}
char last = digit(0);
if (last != '0')
sum.push_back(last);
return string(sum.rbegin(), sum.rend());
}
So I have this assignment where you have to reposition letters in a char array by given number of repositions. The last letter must become first. For example:
Input: Hello 3
Output: lloHe
But if you have a sentence, you have to do it for each word seperately and, what is more, if there are numbers, you must ignore them. So I have trouble dealing with the check for numbers and dealing with seperate words(I use strtok to split them). This is what I have so far:
#include <iostream>
#include <cstring>
using namespace std;
void Reposition(char text[10000], int n, char result[10000])
{
int startIndex = strlen(text)-1;
int k = n-1;
int currentIndex = 0;
for(int i = 0; i < n; i++)
{
result[k] = text[startIndex];
k--;
startIndex--;
currentIndex++;
}
for(int i = 0; i <= startIndex; i++)
{
result[currentIndex] = text[i];
currentIndex++;
}
}
int main()
{
char text[10000];
cin.getline(text,10000);
int n;
cin >> n;
char result[10000];
char *words;
words = strtok(text, " .,");
while(words != NULL)
{
Reposition(text, n, result);
words = strtok(NULL, " .,");
}
for(unsigned i = 0; i <= strlen(result); i++)
cout << result[i];
return 0;
}
Use std::string instead of C-style string
To remove numbers from a string, use std::remove_if from <algorithm>:
std::string s;
. . .
s.erase(std::remove_if(s.begin(), s.end(), ::isdigit), s.end());
To reposition characters in a string, use std::rotate:
std::rotate(s.begin(), s.begin() + 1, s.end());
I did your homework.
Don't know if you are familiar with all this code.
I Also rewrote your reposition code. It looked very messy.....
One time favour from me. Try to learn something from this.
#include <iostream>
#include <cstring>
#include <ctype.h>
using namespace std;
void Reposition(char * text, int len, int n, char * result)
{
int k = n - 1;
for(int i = 0; i < len; i++)
{
result[i] = text[k++];
if(k == len) k = 0;
}
}
int main()
{
char text[10000];
cin.getline(text,10000);
int n;
cin >> n;
char result[10000];
char * word;
char * beginOfWord = text;
char * resultPointer = result;
int wordLen;
while(* beginOfWord)
{
// copy up to somthing from the alphabet
if(!isalpha(* beginOfWord))
{
*resultPointer++ = * beginOfWord++;
continue;
}
// Find the end of this word
word = strpbrk(beginOfWord, " .,0123456789");
if(word != NULL)
{
// len is distance between end of word and begin of word
wordLen = word - beginOfWord;
}
else
{
// Maybe it is the end of the string
wordLen = strlen(beginOfWord);
}
//reposition the word
Reposition(beginOfWord, wordLen, n, resultPointer);
// Move the pointers beyond the word
beginOfWord += wordLen;
resultPointer += wordLen;
}
//Always terminate
*resultPointer ='\x0';
cout << result;
return 0;
}
//reverse will reverse the string starting at position xn and ending at position (yn-1)
void reverse(char *str, int xn, int yn)
{
//positioning the pointers appropriately
char *start = str + xn;
char *end = str + yn - 1;
char temp;
while(start < end)
{
temp = *start;
*start = *end;
*end = temp;
++start;
--end;
}
}
//one of the logic to reposition
void reposition(char *str, int n)
{
int length = strlen(str);
n = (length > n) ? n : (n % length);
reverse(str, 0, n);
reverse(str, n, length);
reverse(str, 0, length);
}
int main()
{
char text[10000];
cin.getline(text,10000);
int n;
cin >> n;
char result[10000];
strcpy(result, text);
cout << "before: " << result << endl;
char *word;
word = strtok(text, " .,");
while(word != NULL)
{
//check if it is not a number
if(isdigit(word[0]) == 0)
{
reposition(word, n);
//find the word postion in text
int word_position = word - text;
//copy the repositioned word in result at its corresponding position.
int i = 0;
while(word[i])
{
result[word_position + i] = word[i];
++i;
}
}
word = strtok(NULL, " .,");
}
cout << "after : " << result << endl;
return 0;
}
Output:
abcd 345 pqrst 321
3
before: abcd 345 pqrst 321
after : dabc 345 stpqr 321
I need to create a generic function that changes from any starting base, to any final base. I have everything down, except my original function took (and takes) an int value for the number that it converts to another base. I decided to just overload the function. I am Ok with changing between every base, but am slightly off when using my new function to take in a string hex value.
The code below should output 1235 for both functions. It does for the first one, but for the second, I am currently getting 1347. Decimal to Hex works fine - It's just the overloaded function (Hex to anything else) that is slightly off.
Thanks.
#include <iostream>
#include <stack>
#include <string>
#include <cmath>
using namespace std;
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, int num);
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, string s);
int main()
{
stack<int> myStack;
string hexNum = "4D3";
switchBasesFunction(myStack, 8, 10, 2323);
cout << endl << endl;
switchBasesFunction(myStack, 16, 10, hexNum);
return 0;
}
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, int num)
{
int totalVal = 0;
string s = to_string(num);
for (int i = 0; i < s.length(); i++)
{
myStack.push(s.at(i) - '0');
}
int k = 0;
while (myStack.size() > 0)
{
totalVal += (myStack.top() * pow(startBase, k++));
myStack.pop();
}
string s1;
while (totalVal > 0)
{
int temp = totalVal % finalBase;
totalVal = totalVal / finalBase;
char c;
if (temp < 10)
{
c = temp + '0';
s1 += c;
}
else
{
c = temp - 10 + 'A';
s1 += c;
}
}
for (int i = s1.length() - 1; i >= 0; i--)
{
cout << s1[i];
}
cout << endl << endl;
}
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, string s)
{
int totalVal = 0;
for (int i = 0; i < s.length(); i++)
{
myStack.push(s.at(i) - '0');
}
int k = 0;
while (myStack.size() > 0)
{
totalVal += (myStack.top() * pow(startBase, k++));
myStack.pop();
}
string s1;
while (totalVal > 0)
{
int temp = totalVal % finalBase;
totalVal = totalVal / finalBase;
char c;
if (temp < 10)
{
c = temp + '0';
s1 += c;
}
else
{
c = temp - 10 + 'A';
s1 += c;
}
}
for (int i = s1.length() - 1; i >= 0; i--)
{
cout << s1[i];
}
cout << endl << endl;
}
Sorry, but I'm having issues understanding your code, so I thought I'd simplify it.
Here's the algorithm / code (untested):
void convert_to_base(const std::string& original_value,
unsigned int original_base,
std::string& final_value_str,
unsigned int final_base)
{
static const std::string digit_str =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if ((original_base > digit_str.length()) || (final_base > digit_str.length())
{
std::cerr << "Base value exceeds limit of " << digit_str.length() << ".\n";
return;
}
// Parse string from right to left, smallest value to largest.
// Convert to decimal.
unsigned int original_number = 0;
unsigned int digit_value = 0;
int index = 0;
for (index = original_value.length(); index > 0; --index)
{
std::string::size_type posn = digit_str.find(original_value[index];
if (posn == std::string::npos)
{
cerr << "unsupported digit encountered: " << original_value[index] << ".\n";
return;
}
digit_value = posn;
original_number = original_number * original_base + digit_value;
}
// Convert to a string of digits in the final base.
while (original_number != 0)
{
digit_value = original_number % final_base;
final_value_str.insert(0, 1, digit_str[digit_value]);
original_number = original_number / final_base;
}
}
*Warning: code not tested via compiler.**
I have a string like str="ABCDEFGHIJK";
need o/p like this str="CBAFEDIHGJK"
am getting "CBA" correctly after that its not printing anything.
can anyone check the following code and let me know where is the problem?
int main()
{
string str="ABCDEFGHIJK";
char str1[10],rev[10];
int n=str.length(),count=0,c=3,k=0,j=0;
for(int i=0;i<n;i++)
{
str1[i]=str[i];
count++;
cout<<str1[i]<<" and "<<count<<"and "<<c<<endl;
if(count==c)
{
cout<<"Entered into if loop"<<count<<"and"<<c<<"and "<<k<<endl;
cout<<c<<" and "<<k<<endl;
while(j<c)
{
rev[j]=str1[c-k-1];
cout<<rev[j]<<" and "<<str1[c-k-1]<<endl;
j++;
k++;
}
count=0;
}
/*else
{
if(count < c && str[i]=='\0')
{
for(int k=0;k<count;k++)
{
rev[k]=str1[count-1];
count--;
count=0;
}
}
}*/
}
cout<<"The string is: "<<rev<<endl;
return 0;
}
Please help me on this.
No need to use a c++ string object for this use-case; just use a normal char *.
Also, always make sure you store enough room for the string null-terminator character ('\0'). This is required as c string functions assume your string is terminated in this way.
Following will reverse string in ansi C89
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void reverse(char *in, char *rev)
{
int i, n;
n = strlen(in);
for(i = n-1; i>=0; i--)
{
rev[n-i-1] = in[i];
}
/* add the null-terminator */
rev[n] = '\0';
}
int main()
{
char *str = "ABCDEFGHIJK";
char str1[12], temp;
char triplet[4];
char rev_triplet[4];
int index;
triplet[3] = '\0';
rev_triplet[3] = '\0';
str1[0] = '\0';
for(index = 0; index < strlen(str); index += 3)
{
memcpy(triplet, str + index, 3 * sizeof(char));
reverse(triplet, rev_triplet);
strcat(str1, rev_triplet);
}
printf("Initial string is: %s\n", str);
printf("Reverse string is: %s\n", str1);
return 0;
}
Outputs
$ ./test
Initial string is: ABCDEFGHIJK
Reverse string is: CBAFEDIHGKJ
If you intend to use C++ (and not C) for this:
#include <algorithm>
#include <iostream>
#include <string>
std::string reverse_triples(std::string s)
{
const unsigned int N = 3;
for (int i = 0, j = N - 1; i < s.length() - (s.length() % N); i += N, j += N)
{
std::swap(s[i], s[j]);
}
return s;
}
int main()
{
std::string s = "ABCDEFGHIJK";
std::string rs = reverse_triples(s);
std::cout << "Reversed Triples: " << rs << std::endl;
return 0;
}
Whatever value of N you need can be modified (and even supplied as a function parameter if you want). You only need to swap the outer characters (so all the elements below N / 2 will be swapped with the elements above N / 2). For N == 3, it is just a single swap. If you want to do it more generically:
#include <algorithm>
#include <iostream>
#include <string>
std::string reverse_substrings(std::string s, unsigned int substring_size)
{
for (int i = 0, j = substring_size - 1; i < s.length() - (s.length() % substring_size); i += substring_size, j += substring_size)
{
std::reverse(s.begin() + i, s.begin() + j + 1);
}
return s;
}
int main()
{
std::string s = "ABCDEFGHIJK";
std::string rs = reverse_triples(s, 4); // passing 3 gets you the same results as before
std::cout << "Reversed Triples: " << rs << std::endl;
return 0;
}
First, let us examine how std::reverse might be implemented. It uses iterators.
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
while ((first!=last)&&(first!=--last)) {
std::iter_swap (first,last);
++first;
}
}
We can extend the logic to use indices instead of iterators, where i and j represent iterators (positions) and s[i] and s[j] represent the data pointed to by the iterators.
void reverse(std::string& s)
{
int i = 0;
int j = s.size();
while ((i != j) && (i != (--j)))
{
std::swap(s[i], s[j]);
++i;
}
}
Now you want to reverse "chunks" rather than the entire string.
void reverse(int n, std::string& s)
{
int beg = 0;
int end = beg + n;
int size = s.size();
// We're going to modify s in place
// So store a copy
std::string copy = s;
s = "";
// Add + 1 to avoid the loop cutting off short
// Or do i <= size / n;
for (int i = 0; i < size / n + 1; i++)
{
std::string chunk(copy.begin() + beg, copy.begin() + end);
// If there's no n sized chunks left
// don't reverse
if (end < size)
reverse(chunk);
s += chunk;
beg += n;
// Don't go past the size of the string
end += (end + n > size ? size - end : n);
}
}
int main()
{
std::string s("ABCDEFGHIJK");
std::string target("CBAFEDIHGJK");
reverse(3, s);
std::cout << s << "|" << target <<"|\n";
std::cout << s.size() << " " << target.size() << "\n"; // 11 11
std::cout << std::boolalpha << (s == target); // true
return 0;
}