C++ : Converting String into an array of Char - c++

I've managed to convert an array of char into a string but now I want to do the other way around, I tried using strcpy in my code but it doesn't seem to give me what I want. The expected result should be 5, I'm getting 40959 as a result
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
string DecToBin(int);
int BinToDec(string);
int main()
{
int x = 5;
string y = DecToBin(x);
reverse(y.begin(), y.end());
int z = BinToDec(y);
cout << z << endl;
}
string DecToBin(int num)
{
char res[16];
for (int n = 15; n >= 0; n--)
{
if ((num - pow(2, n)) >= 0)
{
res[n] = '1';
num -= pow(2, n);
}
else
{
res[n] = '0';
}
}
for (int n = 15; n >= 0; n--)
{
res[n];
}
return res;
}
int BinToDec(string num)
{
char x[16];
strcpy(x, num.c_str());
int res;
for (int n = 15; n >= 0; n--)
{
if (x[n] == '1')
{
res += pow(2, n);
}
}
return res;
}

I can find the following errors:
res is not zero-terminated in DecToBin before it is copied into the string,
res is not initialized in BinToDec,
You reverse the binary representation but try to read it back in the same way you wrote it.
This looks to me like homework, so I leave fixing the code to you. In the event that you really need this productively for something, an easier way to achieve this (that will not be accepted as homework anywhere) is
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
string DecToBin(int num) {
std::bitset<16> b(num);
return b.to_string();
}
int BinToDec(string num) {
std::bitset<16> b(num);
return static_cast<int>(b.to_ulong());
}

Related

C++ Array of random numbers

I have a bit of a problem with this. I've tried to create a function to return a random number and pass it to the array, but for some reason, all the numbers generated are "0".
#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
int generLosNum(int);
int main()
{
srand(time(NULL));
int LosNum;
const int rozmiar = 10;
int tablica[rozmiar];
for(int i=0; i<rozmiar; i++)
{
tablica[i] = generLosNum(LosNum);
cout << tablica[i] <<" ";
}
return 0;
}
int generLosNum(int LosNum)
{
int LosowyNum;
LosowyNum = (rand() % 10);
return (LosNum);
}
So the return for your int generLosNum(int LosNum) was printing 0 because you had it returning LosNum which was initialized equaling to zero. I changed your code so it works and will print out the 10 random numbers.
#include <iostream>
#include <ctime>
#include <iomanip>
using namespace std;
int generLosNum();
int main()
{
srand(time(NULL));
int LosNum = 0;
const int rozmiar = 10;
int tablica[rozmiar];
for (int i = 0; i < rozmiar; i++)
{
tablica[i] = generLosNum();
cout << tablica[i] << " ";
}
return 0;
}
int generLosNum()
{
int LosowyNum;
LosowyNum = (rand() % 10);
return LosowyNum;
}
Change your method generLosNum to the following and the method signature to int generLosNum() and it should work.
int generLosNum()
{
return (rand() % 10);
}
Reason: As others also mentioned in the comments, you were just returning the number that you passed in as parameter and also the logic for this method doesn't even need a parameter.

How do I optimise the code to return the number closest to a given integer, not present in the given list?

I solved this problem statement (Yeah Yeah, I know, I am putting the problem statement below).
Given are an integer X and an integer sequence of length N: p1, …, pN.
Among the integers not contained in the sequence p1, …, pN (not necessarily positive),
find the integer nearest to X, i.e. the integer whose absolute difference with X is the minimum.
If there are multiple such integers, report the smallest such integer
This is the code I used:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
int x = 0;
int n = 0;
std::cin >> x >> n;
std::vector<decltype(x)> vect(n);
bool vect_contains_x = false;
for (auto& elem : vect) {
std::cin >> elem;
if (elem == x) {
vect_contains_x = true;
}
}
int num = 0;
if (!vect_contains_x) {
num = x;
}
else {
std::sort(vect.begin(), vect.end());
while (1) {
static int i = 1;
if (std::find(vect.begin(), vect.end(), x - i) == vect.end()) {
num = x - i;
break;
}
else if (std::find(vect.begin(), vect.end(), x + i) == vect.end()) {
num = x + i;
break;
}
else {
i += 1;
}
}
}
std::cout << num << "\n";
return 0;
}
This code renders the result in 13-18ms.
I was able to get it down to 8-10ms by using the following optimised code:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
int x = 0;
int n = 0;
std::cin >> x >> n;
std::vector<decltype(x)> vect(n);
bool vect_contains_x = false;
for (auto& elem : vect) {
std::cin >> elem;
if (elem == x) {
vect_contains_x = true;
}
}
int num = 0;
if (!vect_contains_x) {
num = x;
}
else {
std::sort(vect.begin(), vect.end());
auto isPresent = [=](auto num) {
for (const auto& elem : vect) {
if (num == elem) {
return true;
}
}
return false;
};
while (1) {
static int i = 1;
if (!isPresent(x - i)) {
num = x - i;
break;
}
else if (!isPresent(x + i)) {
num = x + i;
break;
}
else {
i += 1;
}
}
}
std::cout << num << "\n";
return 0;
}
However, the problem with both the codes (as they both use the same approach) is that,
If there is a large continuous stream of integers in the given list, something like:
1,2,3,4,5,6,7,8,9,10,...,1501
and the X given is
751
The code will need 750 iterations of the for loop, which is a lot. Can we use a better algorithm to find the closest integer?
EDIT:
Got it down to 6ms by using binary_search (Thanks #Sebastian), but still, the algorithm remains the same...
You can see this "cheating" algorithm. It's cheating because the _Find_next method is only in the GCC compiler. Also, with the help of printf and scanf, I accelerated input and output, due to which the program runs faster. I sent it for execution several times and received 4, 6 and 8 ms (6 ms most often):
#include <bitset>
#include <algorithm>
using namespace std;
int main()
{
const int MAX_VALUES = 101;
bitset<MAX_VALUES> bits;
bitset<MAX_VALUES> reversed;
bits.flip();
reversed.flip();
int x, n, t;
scanf("%d %d", &x, &n);
if (n == 0) {
printf("%d", x);
exit(0);
}
for (int i = 0; i < n; i++) {
scanf("%d", &t);
bits.reset(t);
reversed.reset(MAX_VALUES - 1 - t);
}
if (bits[x]) {
printf("%d", x);
exit(0);
}
int rV = bits._Find_next(x);
int lV = MAX_VALUES - 1 - reversed._Find_next(MAX_VALUES - 1 - x);
int d1 = abs(rV - x);
int d2 = abs(lV - x);
if (d1 < d2) {
printf("%d", rV);
} else if (d2 < d1) {
printf("%d", lV);
} else {
printf("%d", min(rV, lV));
}
return 0;
}
I am not saying that this "algorithm" is better than yours. But, as I understand it, you asked for some other solutions, this is one of the possible.
According to your link, the total number of integers is at most 100.
So 100 bits are enough to hold the flags, which numbers appear in the sequence. Those can be held in the processor registers.
The following code shows only the storage, afterwords you would have to chose suitable bit scan operations:
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <limits>
#include <bitset>
using namespace std;
int main() {
bitset<100> flags;
int x = 0;
int n = 0;
int min = std::numeric_limits<int>::max();
int num = 0;
std::cin >> x >> n;
for (int i = 0; i < n; i++) {
int elem;
std::cin >> elem;
flags.set(elem);
}
// then you can shift the result by x bits and do bit scan operations
// there are built-ins depending on the compiler and processor architecture or the portable De Bruijn with multiplications
}
// alternatively (to the shift) you can use two bitsets, and for one set all the elements (elem - x) or for the other (x - elem)

Generating a random value array without repeating

I want to make a method that generates an array with random values between 0 and 6 in it without repeating those values.
This is what I've got:
void randomArray(){
randNum = rand() % 6;
code[0] = randNum
for (int i = 1; i < 4; i++){
randNum = rand() % 6;
code[i] = randNum;
while (code[i] == code[i - 1]){
randNum = rand() % 6;
code[i] = randNum;
}
}
}
But I'm getting repeated values on the random-generated array.
PD: I also need to use a similar method to make an array of enum's.
You could do something like this:
int randomFromSet(std::vector<int>&_set)
{
int randIndex = rand() % _set.size();
int num = _set[randIndex];
_set.erase(_set.begin() + randIndex);
return num;
}
This chooses a random int from a provided set of numbers, and removes that choice from the set so that it can't be picked again.
Used like so:
std::vector<int> mySet {0,1,2,3,4,5,6};
std::cout<<randomFromSet(mySet)<<'\n;
#include <random>
#include <vector>
#include <numeric>
#include <iostream>
using std::cout;
using std::endl;
int main() {
const int sz = 7;
std::vector<int> nums(sz);
std::iota(std::begin(nums), std::end(nums), 0);
std::default_random_engine re;
int i = 8;
while(--i > 0) {
auto my_set{ nums };
std::shuffle(my_set.begin(), my_set.end(), re);
for (auto x : my_set) {
cout << x << " ";
}
cout << endl;
}
}
Im new to c++ , can I add my answer too?
its c-style c++ sorry for that.but its easy to code and to understand at the same time.
#include <iostream> //std::cout
#include <ctime> //time() function
#include <cstdlib> //rand() and srand() functions
void rand_gen(unsigned int arr[],unsigned int sizeofarray)
{
srand((unsigned int)time(0);
for (unsigned int c = sizeofarray ; c > 0 ; c--)
{
unsigned int r = rand()%sizeofarray;
if (arr[r] != 404)
{
std::cout<<"Try No."<<(sizeofarray+1)-c<<" : "<<arr[r]<<"\n";
arr[r] = 404;
} else { c++; }
}
}
int main()
{
unsigned int n[7]={0,1,2,3,4,5,6};
rand_gen(n,7);
std::cin.get();
return 0;
}

Need my current output in Characters which are its int values in C++

d[i] = char(c[i]);
This is not working for me in the below example.
I need my output to be converted to its character values, but after using char(int), its still giving output using the int datatype only.
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin>>str;
int size=str.size();
int len=0;
if (size % 2 == 0)
{
len=size/2;
}
else
{
len=(size/2)+1;
}
int a[len],b[len],c[len],d[len],x,y;
int i=0,j=size-1;
while(i<len)
{
x=(int)str[i];
y=(int)str[j];
if (i == j)
{
a[i]=x;
}
else
{
a[i]=x+y;
}
b[i]=a[i]%26;
c[i]=x + b[i];
d[i]=char(c[i]);
cout<<"l : "<<d[i]<<endl;
i++;
j--;
}
return 0;
}
Your code fails because you are storing the values in an int[] array. d[i]=char(c[i]); is useless because all you are doing is converting an int to a char back to an int again. You are then outputting the array values as-is as int values instead of converting them back to actual char values.
Try something more like this instead:
#include <vector>
#include <string>
using namespace std;
int main()
{
string str;
cin >> str;
int size = str.size();
int len = (size / 2) + (size % 2);
// VLAs are a non-standard compiler extension are are not portable!
// Use new[] or std::vector for portable dynamic arrays...
//
// int a[len], b[len], c[len];
// char d[len];
//
std::vector<int> a(len), b(len), c(len);
std::vector<char> d(len);
int x, y, i = 0, j = (size-1);
while (i < len)
{
x = (int) str[i];
y = (int) str[j];
if (i == j)
{
a[i] = x;
}
else
{
a[i] = x + y;
}
b[i] = a[i] % 26;
c[i] = x + b[i];
d[i] = (char) c[i];
cout << "l : " << d[i] << endl;
++i;
--j;
}
return 0;
}

c++ how print how many element are repeated in 2 array?

I have two arrays and I want to count how many elements are same between two arrays.
I try many times but the output is not correct. The correct should be 6 times
but the output is 4 times in the code.
Note: if s1 is "ss" and s2 is "ss", is the result 2
Here is my code:
#include <iostream>
#include <string>
using namespace std;
int main() {
char s1[] = "FOOBART";
char s2[] = "BFORATO";
int flag=0;
for(int i=0, j=0; i < sizeof(s1) && j < sizeof(s2); ) {
if(s1[i] == s2[j]) {
flag++;
i++;
j++;
} else if(s1[i] < s2[j]) {
i++;
} else {
j++;
}
}
cout << flag;
}
All elements of s1 are present in both strings so the output will be equal to the length of s1. Here is the correct code
#include <iostream>
using namespace std;
int main() {
char s1[] = "FOOBART";
char s2[] = "BFORATO";
int count=0;
for (int i=0; i<sizeof(s1)-1; i++) {
for (int j=0; j<sizeof(s2)-1; j++) {
if (s1[i]==s2[j]) {
count++;
break;
}
}
}
cout<<count<<endl;
}
Hope this will help you
solution using stl algorithms:
#include <iostream>
#include <algorithm>
#include <string>
int main()
{
const std::string s1 = "FOOBART";
std::string s2 = "BFORATO";
int count = 0;
auto beg = begin(s2);
for(auto& elm : s1)
{
auto x = find(beg, end(s2), elm);
if(x != end(s2))
{
*x = *beg;//get rid of elment and reduce the range of search.
++beg;
++count;
}
}
std::cout << count;
return 0;
}