How to generate lexicographical strings of a given length?
I am looking for an algorithm to generate strings (lexicographic order) of length N, in lexicographical order. For example given a length 1, the strings generated are: "a","b","c","d","e","f",g,h,i,j,k...,z.
For length 2, the strings generated should be: "aa","ab","ac","ad",...,"ba","bb",...,"zz".
How could we do this?
Here is what I have done:
void permute(string a, int i, int n, int length)
{
int j;
if (i == length){
string cand = a.substr(0,length);
cout<<cand<<endl;
}
else
{
for (j = i; j <= n; j++)
{
swap((a[i]), (a[j]));
permute(a, i+1,n,length);
swap((a[i]), (a[j]));
}
}
}
While calling "permute(a,0,a.size(),1)" where the string a looks like this:
aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbccccccccccccccccccccddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeffffffffffffffffffffgggggggggggggggggggghhhhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiiiiiijjjjjjjjjjjjjjjjjjjjkkkkkkkkkkkkkkkkkkkkllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmnnnnnnnnnnnnnnnnnnnnooooooooooooooooooooppppppppppppppppppppqqqqqqqqqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrrssssssssssssssssssssttttttttttttttttttttuuuuuuuuuuuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyzzzzzzzzzzzzzzzzzzzz
Generates the correct output but it's repeating the lexicographic strings. If I reduce it to just alphabets I believe strings like "aa", "aaaa" will be missed. So how could we get around this,Any ideas?
I would do a recursive call into a function that simply loops through the alphabet, and call it for each letter placement.
Preliminary testing shows this may work:
#include <iostream>
#include <sstream>
#include <string>
void addLetters(std::string base, int tgt_depth)
{
if (base.length() == tgt_depth) {
std::cout << base << std::endl;
return;
}
for (char letter = 'a'; letter <= 'z'; ++letter) {
std::stringstream ss;
ss << letter;
addLetters(base + ss.str(), tgt_depth);
}
}
int main(int argc, char* argv)
{
// first argument is your "base" -- start with nothing
// second argument is the depth to which to recurse, i.e. how many letters
addLetters("", 2);
}
Assuming you want to see which string is in place M in the lexicographical order of these strings, represent this number in base 26 and than map 0 to a, 1 to b and so on. You will have to add zeros(or a-s) to the left until the string reaches the needed length. Now to solve your problem simply iterate through the integers(up to the number of string of length N which is 26N) and apply the conversion I suggest.
for(i='a';i<='z';i++)
{
recur(new String(i));
}
void recur(String s)
{
if(s.length()==dig)
{
add s to array
return
}
for(i='a';i<='z';i++)
recur(s+i);
}
Although this code is not feasable enough to generate more than 5 digits because there are 26^dig possibilities.And I dont know c++ so i have written the algorithm . But i feel there is nothing in it that a coder i a language cant convert
Related
Good night to everyone!
I am trying to compare 2 strings in c++, using the .compare() function. However, the result i see is not what is expected from this function. Take a look please.
#include <iostream>
#include <string>
using namespace std;
class game
{
private:
char mtx [2][2];
int i = 0, j = 0, a = 0;
std::string matrix1;
std::string xis = "xx";
public:
game();
char winner();
};
game::game()
{
for(i = 0; i<2; i++)
{
for (j = 0; j<2; j++)
{
mtx [i][j] = 'x';
}
}
char game::winner()
{
i = j = 0;
for (j=0; j<2; j++)
{
matrix1 = mtx [0][j]; //string recieve the first line of the matrix.
}
a = xis.compare(matrix1);
cout << a<<endl;
}
int main(void) {
velha game;
velha.winner;
}
When I compile the program the a value printed is neither a '0' nor any other integers. It prints #85.
Notes: I've also tried to use <string.h> and strncmp() using a char array instead of std:: string but with no success.
I was trying to create a game class and I did not put here the other methods because they are not relevant). (also, I use Linux Mint to code)
Can anyone help me please in this context?
#include <iostream>
#include <string>
int main(void) {
std::string first, second;
std::cout << "First String: ";
getline(std::cin, first);
std::cout << "Second Line: ";
getline(std::cin, second);
if (first == second)
std::cout << "Same strings.";
else
std::cout << "Different strings.";
return 0;
}
Explanation: Just taken two strings from the user and matches straightforward without using any much complexity, just used a conditional operation.
For string compare and even strcmp the value returned will be the lexicographical comparison of the two strings. The following are the values you should see:
negative if *this appears before the character sequence specified by the argument in lexicographical order
0 if *this and the character sequence specified are equivalent
positive if *this appears after the character sequence specified by the argument in lexicographical order
If you are looking to get the first column of your matrix, do a string comparison on, you would want to do something like:
for(int col = 0; col < 2; col++) {
matrix1.push_back(mtx[0][col]); // This appends that character to the end of your string
}
If you are looking to get the rows you can just do the following:
matrix1 = mtx[0];
// To ensure you have a null terminated string
// Otherwise you will have garbage.
matrix1.replace(matrix1.begin() + 2, matrix1.end(), 1, "\0");
I have ran through the test with comparing that the matrix contains "xx" and ended up receiving 0. However a much easier comparison is to us operator == to simply return a true or false value.
I was trying to solve a very simple coding question:
Consider an array of numeric strings where each string is a positive
number with anywhere from 1 to 10^6 digits. Sort the array's elements in
non-decreasing, or ascending order of their integer values and print
each element of the sorted array on a new line.
The first line contains an integer n denoting the number of strings
Each of the n subsequent lines contain an INTEGER STRING.
My code is:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i; string s;
cin >> i;
int j = i;
string arr[i];
int cntr = 0;
while (i--){
cin >> s;
arr[cntr] = s;
cntr++;
}
sort(arr, arr+j);
for (auto c: arr)
cout << c << endl;
}
The input is
6
31415926535897932384626433832795
1
3
10
3
5
And my output turns out to be:
1
10
3
3
31415926535897932384626433832795
5
If I make an array and add integer strings to it manually, the above code works fine. Then why is it producing wrong result when it takes input from the website?
PS: Here's the link to the problem:https://www.hackerrank.com/challenges/big-sorting/problem
Firstly use a vector of strings instead of a variable size array of strings (which is not allowed in C++).
The STL sort function uses lexicographical search to sort strings by default. You need to pass your own comparison function in order to sort the integer strings numerically.
Assuming the integer strings don't have leading 0's;
sort(arr.begin(), arr.end(), [] (const string& s1, const string& s2) {
return s1.size() < s2.size() || (s1.size() == s2.size() && s1 < s2);
});
I will give you an alternative solution as C++ already have sorted containers.
Some hints:
Please do not use "using namespace std;"
C++ did not have variable length arrays! So it is much easier to use a container type! In the example, we use a std::multimap which can have elements sorted and allows duplicates.
#include <iostream>
#include <map>
// we want to use our own sorting algorithm for std::multimap
// this needs a functional object with operator() which do the compare
//
// works only for non negative numbers without leading '0's
struct compare
{
bool operator()( const std::string& s1, const std::string& s2 ) const
{
// if the string contains a number as text, we can asume that
// a number which has less characters is lesser
if ( s1.size() < s2.size() ) return true;
// if the size is bigger, the numerical value is bigger
if ( s1.size() > s2.size() ) return false;
// if both are equal length
// so we simply compare lexigraphical
// this works because a bigger diggit char always means a
// bigger numerical value
return s1 < s2;
}
};
int main()
{
// instead of later sort, we use a sorted container, multiset because we can use duplicates
std::multiset<std::string, compare> data;
// read data as in your code
int numberOfElementsToRead;
std::string tmpInput;
std::cin >> numberOfElementsToRead;
while (numberOfElementsToRead--)
{
std::cin >> tmpInput;
data.insert( tmpInput ); // insert automatically sorts
}
// print out the container
for ( auto& s: data )
{
std::cout << s << std::endl;
}
}
This won't work:
int i;
cin >> i;
string arr[i];
If you need to dynamically resize an array, use std::vector (or new/delete if you really must).
int i;
cin >> i;
std::vector<std::string> arr(i);
In terms of why the sorting fails, you are sorting the numbers alphabetically, which means anything with a '1' at the front will appear first. Sort based on the numeric value instead:
auto compareStringsNumerically = [](const std::string& a, const std::string& b) {
return std::stoi(a) < std::stoi(b); //< compare integer values
};
std::sort(arr, arr + j, compareStringsNumerically);
I would like to know if there is already an implementation in CPP to find all permutations of n characters of length k(1,2,3,4 etc) with repetitions. I hope there is but i could not find.
For example if string= (A,B,C,D) and i want find all permutations of string with repetitions of length k =2.
The output will be something like :
AA
AB
AC
AD
.
.
.
DD
total permutations of 16.
Simple recursive solution which will work for you for sure.
Let me first re-write your specification: Print all permutations with repetition of characters
Given a string of length n, print all permutation of the given string.
Repetition of characters is allowed
For a given string of size n, there will be n^k possible strings of length "length". The idea is to start from an empty output string (we call it prefix in following code). One by one add all characters to prefix. For every character added, print all possible strings with current prefix by recursively calling for "length" equals to "length"-1.
#include <string>
#include <iostream>
void print_str(const char*,std::string,const int, const int);
int main()
{
int lenght = 2;
char str[] = {'A', 'B', 'C', 'D'};
int n = sizeof str;
print_str(str, "", n, lenght); //Note: this function works on all cases and not just the case above
return 0;
}
// The main recursive method to print all possible strings of length "length"
void print_str(const char str[],std::string prefix,const int n, const int lenght)
{
if (lenght == 1)
{
for (int j = 0; j < n; j++)
std::cout << prefix + str[j] << std::endl;
}//Base case: lenght = 1, print the string "lenght" times + the remaining letter
else
{
// One by one add all characters from "str" and recursively call for "lenght" equals to "lenght"-1
for (int i = 0; i < n; i++)
// Next character of input added
print_str(str, prefix + str[i], n, lenght - 1);
// "lenght" is decreased, because we have added a new character
}
}
Here is the execution of the code above:
References:
http://www.geeksforgeeks.org/print-all-permutations-with-repetition-of-characters/
http://www.geeksforgeeks.org/print-all-combinations-of-given-length/
Update: this update is writen answring the following spec.
I need one more help!! as i am new to CPP programming. Suppose if
length = 3 how can i make it to get all permutations starting from
length = 1 to length = 3 together in an array. Means to get all the
permutations of length =1, length =2 and length = 3 together stored in
an array
#include <string>
#include <iostream>
#include <vector>
void print_str(const char*,std::string,const int, const int);
std::vector<std::string> permutations ; // the vector permutations which will hold all the permutations,
//if you want you can use it for later use or you can use the array below which is nothing than a copy of this vector.
int NumberOfPermutations = 0; // this variable holds the number of permutations
int main()
{
int lenght = 3;
char str[] = {'A', 'B', 'C', 'D'};
int n = sizeof str;
//here we loop through all the possible lenghts 1, 2 and 3
for (int k = 1; k <= lenght; k++)
{
print_str(str, "", n, k); //Note: this function works on all cases and not just the case above
}
std::string* permut_array = new std::string[NumberOfPermutations]; // the array that we will use to store the permutations in
std::copy(permutations.begin(), permutations.end(), permut_array); // here we copy the vector into the array
//if you want you can use your array to print the permutation as folow
for (int k = 0; k < NumberOfPermutations; k++)
{
std::cout << permut_array[k] << std::endl;
}
return 0;
}
// The main recursive method to print all possible strings of length "length"
void print_str(const char str[],std::string prefix,const int n, const int lenght)
{
if (lenght == 1)
{
for (int j = 0; j < n; j++)
{
// i commented this ligne so that if you want to use your array to print your permutations you will not get a screnn with permutations printed 2 times
//std::cout << prefix + str[j] << std::endl;
permutations.push_back(prefix + str[j]); // the vector that we will use to store the permutations in
}
}//Base case: lenght = 1, print the string "lenght" times + the remaining letter
else
{
// One by one add all characters from "str" and recursively call for "lenght" equals to "lenght"-1
for (int i = 0; i < n; i++)
// Next character of input added
print_str(str, prefix + str[i], n, lenght - 1);
// "lenght" is decreased, because we have added a new character
}
NumberOfPermutations = permutations.size();
}
you can use std::next_permutation() as πάντα ῥεῖ said, but since you want to define the length and the char with repetitions, you can do something easy to realize it, as:
std::string s = "aabbccdd";
std::set<std::string> string_set;
std::sort(s.begin(), s.end());
do {
string_set.insert(s.substr(0, 2));
} while(std::next_permutation(s.begin(), s.end()));
for(auto i = string_set.begin(); i != string_set.end(); ++i)
std::cout << *i << std::endl;
This just isn't a permutation, which probably explains why you can't find an answer.
What you are actually asking is how to print the numbers 0..k-1 in base n, using digits A,B,C,D. I'll rewrite your example with familiar digits 0,1,2,3 :
00
01
02
03
10
11
12
13
..
33
There's no standard C++ method for this, but now that you know what it's called there's plenty of code on the web. Or just write it yourself. Hint: the last digit of i has value i % n.
This solution works out for all standard container and also static arrays. I think this can be used also for classes and structures
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>
#include <iterator>
template<typename InputIt, typename T>
bool nextPermutationWithRepetition(InputIt begin, InputIt end, T from_value, T to_value) {
auto it = std::find_if_not(std::make_reverse_iterator(end),
std::make_reverse_iterator(begin),
[&to_value](auto current) { return to_value == current; });
if (it == std::make_reverse_iterator(begin))
return false;
auto bound_element_iterator = std::prev(it.base());
(*bound_element_iterator)++;
std::fill(std::next(bound_element_iterator), end, from_value);
return true;
}
int main() {
std::list<int> vec(3, 0);
do {
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
} while (nextPermutationWithRepetition(vec.begin(), vec.end(), 0, 2));
return 0;
}
Okay so I'm working a calculator program that takes in a user input(ex. "(3+(4+12))"), and I need to parse the user's input and store it in an array of strings but I am having trouble doing so. My code currently is this
void parseInput(string input) {
vector <string> input_vector;
for(int i = 0; i < input.size(); ++i) {
if(isdigit(input.at(i)) == 0 && isdigit(input.at(i + 1)) == 0) {
++i;
input_vector.push_back((input.at(i) + input.at(i+1)));
}
else {
input_vector.push_back(input.at(i));
}
}
for(int i = 0; i < input_vector.size(); ++i) {
cout << endl << input_vector[i];
}
}
I know my problem is coming from trying to add a char to an vector of strings, but how would I get each char in the string and keep it as a string to store into my vector. Or is there a better way to parse this out??
edit
Okay so what I am having the most trouble with is the problems that come from the 12 splitting up into two separate chars "1 * 2" How would I go about so that it represents 12 and doesn't split it up???
Here is a solution (using c++11):
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
int main() {
std::string const input = "(3+(4+12))";
std::vector<std::string> chars(input.length());
// Maps each character of `input` to `std::string`
// with that character and saves the results in
// corresponding position in `chars` vector:
std::transform(input.cbegin(), input.cend(), chars.begin(),
[](char c) {
// One of the ways to cast `char` to `std::string`:
return std::string(1, c);
});
// To be sure it works properly, it prints
// generated strings:
for (size_t i = 0; i < chars.size(); ++i) {
std::cout << chars[i];
}
std::cout << std::endl;
}
The answer is u need to split the string into tokens, i have given an example which will add 4 to 12, to make it 16, but think that the string does'nt have any brackets, suppose if the user entered 4+12 and u need to add it you can do the following:
char string[10], nstr[10];
int p=0, a=0, b=0, op=0;
cin>>string; // input string
While (string[i]!='+' || string[i]!='-')
{
nstr[p]=string[i]; // copy the contents of string to nstr.
p++;
i++;
}// loop exits if the string[i] reaches to the operator (+/-*).
nstr[p]='\0';
a=atoi(nstr);// convert the string to integer.
op=i;// this will hold the position of array of the operator in the string.
i++;
p=0;
while (string[i]!='\0')
{
nstr[p]=string[i];// this will copy the contents of the string after the operator.
i++;
p++;
}
nstr[p]='\0';
b=atoi(nstr);
if (string[op]=='+')// check what the user want to do. Add/subtract/divide etc.
c=a+b;
else if (string[op]=='-')
c=a-b;
This program is not tested but will work, if not then use the logic in your program, like i did in my program, this will not take 1 and 2 sepratly, instead it will take 4 and 12, you can type more charaters but is limited to long, i used int here to get the return value of atoi(), hope this helps u...
What I am trying to do is to find a faster way to do the same program but execute faster.
#include <cstdio>
#include <cstring>
int main ()
{
int br=0, c, n, b, e, i, q, g;
char t[7000], a[7000];
scanf("%d" ,&n);
for (g=0; g<n; g++) // number of test cases
{
scanf ("%7000s",&t);
c=strlen(t);
scanf ("%7000s",&a);
b=strlen(a);
for (i=0; i<b; i++) // comparing them
{
for (q=0; q<c; q++)
{
if (a[i]==t[q] && a[i]!='\0' && t[q]!='\0')
{
br++;a[i]='\0';t[q]='\0';
}
}
}
printf("%d \n", br);
br=0;
}
return 0;
}
The program itself does this:
1st input: Number of test cases
2nd: You must input A array and B array for every test case
the program must check if there are any common letters from B to match with A and if there are, to output how much they are.
Example input:
2
qwerty
abc
abcde
bcex
Output:
0
3
What I need is to make it run faster.
Any help is apreciated. :)
Its better to make a hash of every character in both strings. Each character corresponds to an ASCII value. Store count of each character in some other array for both strings. Compare the hash arrays.
Place your input in two sorted containers of char eg deques. Then perform a set intersection and measure the size of the result. This should drop the complexity significantly
EDIT
example of ammending a sorted deque with user input
void addChar2Deque(char newChar, std::deque<char> &sorted_cont) {
sorted_cont.insert(std::lower_bound(sorted_cont.begin(), sorted_cont.end(), newChar), newChar);
}
If you can only have your input in prefetched data, then you can just sort that data, eg for array of char sized N
std::sort(prefetched_data, prefetched_data+N);
In any case you'll end up with two containers (deque or C array) that can be compared with std::set_intersection
std::vector<char> result;
std::set_intersection(std::begin(cont1), std::end(cont1),
std::begin(cont2), std::end(cont2), std::back_inserter(result));
return result.size();
In keeping with the mantra of C code with C++ headers, this is the lookup table method I referred to. The resulting complexity is O(N+M) where N and M are the lengths of your respective strings. Since it is a foregone conclusion each char in each string must be visited at least once (and in this case no more than that), I'm somewhat comfortable in suggesting algorithm-wise it would be hard to do better without reaching into the asm bag-o-tricks.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
int main()
{
int n;
if (scanf("%d", &n) != 1 || n < 0)
return EXIT_FAILURE;
while (n-- >0)
{
char a[7000], b[7000];
if (scanf ("%7000s", a) == 1 && scanf ("%7000s", b) == 1)
{
unsigned short table[1 << CHAR_BIT] = {0};
unsigned int answer = 0;
const char *p;
for (p=b; *p; ++table[(unsigned char)*p++]);
for (p=a; *p; ++p)
{
if (table[(unsigned char)*p])
{
--table[(unsigned char)*p];
++answer;
}
}
printf("%u\n", answer);
}
}
return EXIT_SUCCESS;
}