how to shuffle char "abcdefghijklmnopqrstuvwxyz" without repeating - c++

const char chars[] = "abcdef ....";
char result[...];
memcpy(result, chars, sizeof(chars));
for (unsigned i = 0; i < (sizeof(chars)-1); ++i) {
unsigned j = rand() % sizeof(chars);
char tmp = result[j];
result[j] = result[i];
result[i] = tmp;
}
problem writing the result to a text file.

The answer to "how to shuffle" something in C++ is to use one of the standard library's shuffling algorithms. An easy way to do it would be to put it in an std::string, and use std::random_shuffle:
std::string s = "abcdef ...." ;
std::random_shuffle(s.begin(), s.end());
You can also do it with an array:
char letters[] = {'a', 'b', ..... };
std::random_shuffle(letters, letters+26);

Here you go: Fisher–Yates shuffle.
And a C++ implementation.

Your problem is that the character value 0 isn't mapped to A. Rather, a character which will will be printed as A is equal to 65. You can see the full table here, if you ever need it.
Anyway, the code solution is simple.
Instead of
cout<<letter[i]<<" ";
You can do:
cout<<letter[i]+'A'-1<<" ";
(the -1 is because you numbered the letters from 1 to 26 instead o 0 to 25).

const char chars[] = "abcdef ....";
char result[...];
memcpy(result, chars, sizeof(chars));
for (unsigned i = 0; i < (sizeof(chars)-1); ++i) {
unsigned j = rand() % sizeof(chars);
char tmp = result[j];
result[j] = result[i];
result[i] = tmp;
}
If you use STL then std::random_shuffle is preferred.

Related

If a string is an array of char, how do you convert it into an array of interger

I kept getting an error with this loop. If there are something i missed, please help. Thank You!
int main(){
string hasil;
int cod[5];
hasil = "99999";
for(int i = 0; i < 5; i++){
cod[i] = stoi(hasil[i]);
}
for(int i = 0; i < 5; i++){
cout << cod[i] + 1;
}
std::stoi() takes a std::string, not a char. But std::string does not have a constructor that takes only a single char, which is why your code fails to compile.
Try one of these alternatives instead:
cod[i] = stoi(string(1, hasil[i]));
cod[i] = stoi(string(&hasil[i], 1));
string s;
s = hasil[i];
cod[i] = stoi(s);
char arr[2] = {hasil[i], '\0'};
cod[i] = stoi(arr);
stoi is for converting entire strings to integers, but you're only giving it single characters.
You could either build strings from each character like so:
cod[i] = std::stoi(std::string(1, hasil[i])); // the 1 means "repeat char one time"
Or calculate the actual integer yourself using a bit of ascii math (assuming everything is a valid digit):
cod[i] = hasil[i] - '0'; // now '0' - '0' returns 0, '5' - '0' returns 5, etc...
The below complete working program shows how you can achieve what you want:
#include <iostream>
int main(){
std::string hasil;
int cod[5];
hasil = "99999";
for(int i = 0; i < 5; ++i)
{
cod[i] = hasil[i] - '0';
}
for(int i = 0; i < 5; i++){
std::cout << cod[i];
}
return 0;
}
The output of the above program can be seen here.
std::stoi only accpet std::string or std::wstring as an argument type. But hasil[i] is a char
In C++, '0' to '9' is guarantee to be ascending in ACSII values, so, you can do this:
cod[i] = hasil[i] - '0';

Padding specified number of zeros to a char array

I want to pad a given char array to make it a 15 character array.
For eg. if the array contains two characters 1, 2 then 13 0 characters should be padded to make in 000000000000012 and if contains five characters then 10 0s should be padded. The resultant array should contain 15 characters always.
Found one solution here but that’s for stl string I need similar solution for char arrays. Please help.
What I have tried is below:
char moneyArray[256];
memset(moneyArray, 0, 256);
for(int i=0;i<(15-strlen(moneyArray))-1;i++)
sprintf(moneyArray,"0%s",moneyArray);
But I am looking for a standard solution if possible using a std function may be?
You can use the pad function below:
#include <iostream>
#include <cstring>
void pad(char *s, int n, int c) {
char *p = s + n - strlen(s);
strcpy(p, s);
p--;
while (p >= s) { p[0] = c; p--; }
}
int main () {
char b[16] = "123";
pad(b, 15, '0');
std::cout << b << std::endl;
return 0;
}
If you're fine with std::string (and I think you should be), you can make use of its fill constructor:
char s[] = "12";
std::string padded = std::string( (15 - strlen(s) ), '0').append(s);
Of course you might want to check whether strlen(s) > 15 first.
You have various options; one of them would be (again under the assumption we already know that moneyArray contains a string and is a 16-byte buffer at least):
size_t len = strlen(moneyArray);
memmove(moneyArray + 15 - len, moneyArray, len + 1);
memset(moneyArray, '0', 15 - len);
you could just write code to move the chars up
char str[10] = "123456";
padStart(str, 7, '0');
str would become "0123456". be sure the char array is large enough to fit the longer string
void padStart(char *str, int len, char padChar)
{
// find the null terminator
int strLen = 0;
while (str[strLen] != '\0')
{
strLen++;
};
// is there anything to actually do
if (strLen < len)
{
// move the string up to the given length
for (int i = 0; i <= strLen; i++) // notice the '<=' to include the \0 terminator
{
str[len - i] = str[strLen - i];
}
// add padChar to the start
for (int i = 0; i < len - strLen; i++)
{
str[i] = padChar;
}
}
}

How to replace certain items in a char array with an integer in C++?

Below is an example code that is not working the way I want.
#include <iostream>
using namespace std;
int main()
{
char testArray[] = "1 test";
int numReplace = 2;
testArray[0] = (int)numReplace;
cout<< testArray<<endl; //output is "? test" I wanted it 2, not a '?' there
//I was trying different things and hoping (int) helped
testArray[0] = '2';
cout<<testArray<<endl;//"2 test" which is what I want, but it was hardcoded in
//Is there a way to do it based on a variable?
return 0;
}
In a string with characters and integers, how do you go about replacing numbers? And when implementing this, is it different between doing it in C and C++?
If numReplace will be in range [0,9] you can do :-
testArray[0] = numReplace + '0';
If numReplace is outside [0,9] you need to
a) convert numReplace into string equivalent
b) code a function to replace a part of string by another evaluated in (a)
Ref: Best way to replace a part of string by another in c and other relevant post on SO
Also, since this is C++ code, you might consider using std::string, here replacement, number to string conversion, etc are much simpler.
You should look over the ASCII table over here: http://www.asciitable.com/
It's very comfortable - always look on the Decimal column for the ASCII value you're using.
In the line: TestArray[0] = (int)numreplace; You've actually put in the first spot the character with the decimal ASCII value of 2. numReplace + '0' could do the trick :)
About the C/C++ question, it is the same in both and about the characters and integers...
You should look for your number start and ending.
You should make a loop that'll look like this:
int temp = 0, numberLen, i, j, isOk = 1, isOk2 = 1, from, to, num;
char str[] = "asd 12983 asd";//will be added 1 to.
char *nstr;
for(i = 0 ; i < strlen(str) && isOk ; i++)
{
if(str[i] >= '0' && str[i] <= '9')
{
from = i;
for(j = i ; j < strlen(str) && isOk2)
{
if(str[j] < '0' || str[j] > '9')//not a number;
{
to=j-1;
isOk2 = 0;
}
}
isOk = 0; //for the loop to stop.
}
}
numberLen = to-from+1;
nstr = malloc(sizeof(char)*numberLen);//creating a string with the length of the number.
for(i = from ; i <= to ; i++)
{
nstr[i-from] = str[i];
}
/*nstr now contains the number*/
num = atoi(numstr);
num++; //adding - we wanted to have the number+1 in string.
itoa(num, nstr, 10);//putting num into nstr
for(i = from ; i <= to ; i++)
{
str[i] = nstr[i-from];
}
/*Now the string will contain "asd 12984 asd"*/
By the way, the most efficient way would probably be just looking for the last digit and add 1 to it's value (ASCII again) as the numbers in ASCII are following each other - '0'=48, '1'=49 and so on. But I just showed you how to treat them as numbers and work with them as integers and so. Hope it helped :)

Finding common characters in two strings

I am coding for the problem in which we got to count the number of common characters in two strings. Main part of the count goes like this
for(i=0; i < strlen(s1); i++) {
for(j = 0; j < strlen(s2); j++) {
if(s1[i] == s2[j]) {
count++;
s2[j] = '*';
break;
}
}
}
This goes with an O(n^2) logic. However I could not think of a better solution than this. Can anyone help me in coding with an O(n) logic.
This is very simple. Take two int arrays freq1 and freq2. Initialize all its elements to 0. Then read your strings and store the frequencies of the characters to these arrays. After that compare the arrays freq1 and freq2 to find the common characters.
It can be done in O(n) time with constant space.
The pseudo code goes like this :
int map1[26], map2[26];
int common_chars = 0;
for c1 in string1:
map1[c1]++;
for c2 in string2:
map2[c2]++;
for i in 1 to 26:
common_chars += min(map1[i], map2[i]);
Your current code is O(n^3) because of the O(n) strlens and produces incorrect results, for example on "aa", "aa" (which your code will return 4).
This code counts letters in common (each letter being counted at most once) in O(n).
int common(const char *a, const char *b) {
int table[256] = {0};
int result = 0;
for (; *a; a++)table[*a]++;
for (; *b; b++)result += (table[*b]-- > 0);
return result;
}
Depending on how you define "letters in common", you may have different logic. Here's some testcases for the definition I'm using (which is size of the multiset intersection).
int main(int argc, char *argv[]) {
struct { const char *a, *b; int want; } cases[] = {
{"a", "a", 1},
{"a", "b", 0},
{"a", "aa", 1},
{"aa", "a", 1},
{"ccc", "cccc", 3},
{"aaa", "aaa", 3},
{"abc", "cba", 3},
{"aasa", "asad", 3},
};
int fail = 0;
for (int i = 0; i < sizeof(cases) / sizeof(*cases); i++) {
int got = common(cases[i].a, cases[i].b);
if (got != cases[i].want) {
fail = 1;
printf("common(%s, %s) = %d, want %d\n",
cases[i].a, cases[i].b, got, cases[i].want);
}
}
return fail;
}
You can do it with 2n:
int i,j, len1 = strlen(s1), len2 = strlen(s2);
unsigned char allChars[256] = { 0 };
int count = 0;
for( i=0; i<len1; i++ )
{
allChars[ (unsigned char) s1[i] ] = 1;
}
for( i=0; i<len2; i++ )
{
if( allChars[ (unsigned char) s1[i] ] == 1 )
{
allChars[ (unsigned char) s2[i] ] = 2;
}
}
for( i=0; i<256; i++ )
{
if( allChars[i] == 2 )
{
cout << allChars[i] << endl;
count++;
}
}
Following code traverses each sting only once. So the complexity is O(n). One of the assumptions is that the upper and lower cases are considered same.
#include<stdio.h>
int main() {
char a[] = "Hello world";
char b[] = "woowrd";
int x[26] = {0};
int i;
int index;
for (i = 0; a[i] != '\0'; i++) {
index = a[i] - 'a';
if (index > 26) {
//capital char
index = a[i] - 'A';
}
x[index]++;
}
for (i = 0; b[i] != '\0'; i++) {
index = b[i] - 'a';
if (index > 26) {
//capital char
index = b[i] - 'A';
}
if (x[index] > 0)
x[index] = -1;
}
printf("Common characters in '%s' and '%s' are ", a, b);
for (i = 0; i < 26; i++) {
if (x[i] < 0)
printf("%c", 'a'+i);
}
printf("\n");
}
int count(string a, string b)
{
int i,c[26]={0},c1[26]={};
for(i=0;i<a.length();i++)
{
if(97<=a[i]&&a[i]<=123)
c[a[i]-97]++;
}
for(i=0;i<b.length();i++)
{
if(97<=b[i]&&b[i]<=123)
c1[b[i]-97]++;
}
int s=0;
for(i=0;i<26;i++)
{
s=s+abs(c[i]+c1[i]-(c[i]-c1[i]));
}
return (s);
}
This is much easier and better solution
for (std::vector<char>::iterator i = s1.begin(); i != s1.end(); ++i)
{
if (std::find(s2.begin(), s2.end(), *i) != s2.end())
{
dest.push_back(*i);
}
}
taken from here
C implementation to run in O(n) time and constant space.
#define ALPHABETS_COUNT 26
int commonChars(char *s1, char *s2)
{
int c_count = 0, i;
int arr1[ALPHABETS_COUNT] = {0}, arr2[ALPHABETS_COUNT] = {0};
/* Compute the number of occurances of each character */
while (*s1) arr1[*s1++-'a'] += 1;
while (*s2) arr2[*s2++-'a'] += 1;
/* Increment count based on match found */
for(i=0; i<ALPHABETS_COUNT; i++) {
if(arr1[i] == arr2[i]) c_count += arr1[i];
else if(arr1[i]>arr2[i] && arr2[i] != 0) c_count += arr2[i];
else if(arr2[i]>arr1[i] && arr1[i] != 0) c_count += arr1[i];
}
return c_count;
}
First, your code does not run in O(n^2), it runs in O(nm), where n and m are the length of each string.
You can do it in O(n+m), but not better, since you have to go through each string, at least once, to see if a character is in both.
An example in C++, assuming:
ASCII characters
All characters included (letters, numbers, special, spaces, etc...)
Case sensitive
std::vector<char> strIntersect(std::string const&s1, std::string const&s2){
std::vector<bool> presents(256, false); //Assuming ASCII
std::vector<char> intersection;
for (auto c : s1) {
presents[c] = true;
}
for (auto c : s2) {
if (presents[c]){
intersection.push_back(c);
presents[c] = false;
}
}
return intersection;
}
int main() {
std::vector<char> result;
std::string s1 = "El perro de San Roque no tiene rabo, porque Ramon Rodriguez se lo ha cortado";
std::string s2 = "Saint Roque's dog has no tail, because Ramon Rodriguez chopped it off";
//Expected: "S a i n t R o q u e s d g h l , b c m r z p"
result = strIntersect(s1, s2);
for (auto c : result) {
std::cout << c << " ";
}
std::cout << std::endl;
return 0;
}
Their is a more better version in c++ :
C++ bitset and its application
A bitset is an array of bool but each Boolean value is not stored separately instead bitset optimizes the space such that each bool takes 1 bit space only, so space taken by bitset bs is less than that of bool bs[N] and vector bs(N). However, a limitation of bitset is, N must be known at compile time, i.e., a constant (this limitation is not there with vector and dynamic array)
As bitset stores the same information in compressed manner the operation on bitset are faster than that of array and vector. We can access each bit of bitset individually with help of array indexing operator [] that is bs[3] shows bit at index 3 of bitset bs just like a simple array. Remember bitset starts its indexing backward that is for 10110, 0 are at 0th and 3rd indices whereas 1 are at 1st 2nd and 4th indices.
We can construct a bitset using integer number as well as binary string via constructors which is shown in below code. The size of bitset is fixed at compile time that is, it can’t be changed at runtime.
For more information about bitset visit the site : https://www.geeksforgeeks.org/c-bitset-and-its-application
The code is as follows :
// considering the strings to be of lower case.
int main()
{
string s1,s2;
cin>>s1>>s2;
//Declaration for bitset type variables
bitset<26> b_s1,b_s2;
// setting the bits in b_s1 for the encountered characters of string s1
for(auto& i : s1)
{
if(!b_s1[i-'a'])
b_s1[i-'a'] = 1;
}
// setting the bits in b_s2 for the encountered characters of string s2
for(auto& i : s2)
{
if(!b_s2[i-'a'])
b_s2[i-'a'] = 1;
}
// counting the number of set bits by the "Logical AND" operation
// between b_s1 and b_s2
cout<<(b_s1&b_s2).count();
}
No need to initialize and keep an array of 26 elements (numbers for each letter in alphabet). Just fo the following:
Using HashMap store letter as a key and integer got the count as a value.
Create a Set of characters.
Iterate through each string characters, add to the Set from step 2. If add() method returned false, (means that same character already exists in the Set), then add the character to the map and increment the value.
These steps are written considering Java programming language.
Python Code:
>>>s1='abbc'
>>>s2='abde'
>>>p=list(set(s1).intersection(set(s2)))
>>print(p)
['a','b']
Hope this helps you, Happy Coding!
can be easily done using the concept of "catching" which is a sub-algorithm of hashing.

std::string part into integer

I have a std::string: 01001, I want to get each number:
std::string foo = "01001";
for (int i=0; i < foo.size(); ++i)
{
int res = atoi( foo[i] ); // fail
int res = atoi( &foo[i] ); // ok, but res = 0 in any case
}
How to do that?
This is the easiest way I see:
std::string foo = "01001";
for (int i=0; i < foo.size(); ++i)
{
int res = foo[i] - '0';
}
If you know all characters of foo are digits, you can use (int) (foo[i] - '0') which subtracts the ascii value of '0' from the character. This works for all digits because their ascii values are consecutive.
Your first attempt fails because foo[i] is a single char, while atoi() takes a cstring. Your second attempt fails because &foo[i] is a reference to that character.
Each digit can be obtained by simply using subtraction:
int res = foo[i] - '0';
atoi takes a null-terminated string, not an individual character. The subtraction approach works because the ten decimal digits are guaranteed to be consecutive in the character set (obviously, if there is a chance that you'll have nondigit characters in the string, you'll want to do proper error handling).
One simple way, very close to what you have, would be to insert the char into a predefined string, as such:
std::string foo = "01001";
char str[] = {" "};
for (int i=0; i < foo.size(); ++i)
{
str[0] = foo[i];
int res = atoi( str );
}