How do I treat a char as a string in this question? - c++

Hello I am doing the leetcode problem in C++ called Interger to Roman and here is my following code:
class Solution {
public:
string intToRoman(int num) {
map<char,int> mp ={
{'I', 1},
{'IV', 4},
{'V', 5},
{'IX', 9 },
{'X', 10},
{'XL', 40},
{'L', 50},
{'XC', 90},
{'C', 100},
{'CD', 400},
{'D', 500},
{'CM', 900},
{'M', 1000}
};
string roman = "";
//iterating from the bottom of the map
for(auto it= mp.rbegin(); it!= mp.rend(); it++){
char ch = it->first;
int val = it->second;
if((num/val) > 0){
//this is giving us how many times the string/char of the roman
//will be used
int count = num/val;
string to_add(count,ch);
roman = roman + to_add;
num = num%val;
}
}
return roman;
}
};
I would really appreicitate if you could tell me what is wrong with the code. It passes for the value 3 but fails for eg. 58

a better approach is to accualy emulate what roman numbers are formed:
1-3 -> add 1 (same group)
4 -> sub 1 form 5 (next group - current group)
5-8 -> add 1 at 5 and so on
try to figure out a pattern (btw its always 1 added to prev catttergory) so a recursive function will work? or make a calculator for adding 1 until the number is done

Related

For loop output in C++

I'm trying to write a simple program creating a cluster of k-neighbours for some example data in C++. So far I'm by the first iteration of the algorythm. Would someone explain why do I have so strange output of the string point[] = {...} array? I expect just letters like {A B C D .. H}, but instead have output like this:
A C2 2
4B C1 2.23607
9C C1 2.82843
17D C1 3.60555
30E C2 1
31F C1 2.23607
36G C2 0
36H C1 0
36
Process returned 0 (0x0) execution time : 0.031 s
Press any key to continue.
Where do the numbers before Letters come from?
And here is the code:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
char point[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
float x[] = {1, 3, 4, 5, 1, 4, 1, 2};
float y[] = {3, 3, 3, 3, 2, 2, 1, 1};
float m1[] = {x[(sizeof(x)/sizeof(float))-1], y[(sizeof(y)/sizeof(float))-1]};
float m2[] = {x[(sizeof(x)/sizeof(float))-2], y[(sizeof(y)/sizeof(float))-2]};
string group[8];
float sumdq =0;
for(int i=0;i<=sizeof(point)-1;i++)
{
float d1 = sqrt(pow(x[i]-m1[0],2) + pow(y[i]-m1[1],2));
float d2 = sqrt(pow(x[i]-m2[0],2) + pow(y[i]-m2[1],2));
if(d1<d2)
{
group[i] = "C1";
sumdq =sumdq + pow(d1,2);
cout<<point[i]<< " "<<group[i]<< " "<<d1<<endl;
}
else
{
group[i] = "C2";
sumdq =sumdq + pow(d2,2);
cout<<point[i]<< " "<<group[i]<< " "<<d2<<endl;
}
cout<<sumdq;
}
return 0;
}
OK, now I get it. I,ve put cout<< inside the loop, and that was the problem. Thank you 463035818_is_not_a_number. And thanks tadman for hint with std::vector. BTW, is the only option to show size of an array? isn't there anything like x.length() in Python?
Anyway thak you alot for answares

Finding permutation and combination in C++

I want to find a series of numbers of dynamic length in C++. Suppose I have 2 groups of numbers: arr1[3] = {1, 3, 8} and arr2[4] = {2, 9}, then the expected output is:
'1, 2',
'1, 9',
'3, 2',
'3, 9',
'8, 2',
'8, 9'.
However, if there are 3 groups now : arr1[3] = {1, 3, 8}, arr2[2] = {2, 9} and arr3[5] = {1, 3, 9} then the output should be:
'1, 2, 1',
'1, 2, 3',
'1, 2, 9',
'1, 9, 1',
'1, 9, 3',
'1, 9, 9',
'3, 2, 1',
'3, 2, 3',
'3, 2, 9',
'3, 9, 1',
'3, 9, 3',
'3, 9, 9',
and so on...
So there will 3 x 2 x 3 = 18 outcomes. I got the outcome for 2 groups and 3 groups using respective numbers of for loops.
See this code for 2 groups:
for(int i=1;i<=5;i++) {
for (int j=1;j<=5;j++) {
cout << i << "," << j << "," << endl;
}
}
But then I have to use different codes for different value of group number and have to use switch statement or if-else statement to choose that portion of code.
This will be a great help. Thanks in advance!
I used vector instead of arrays, as they are way easier to deal with.
The trick is to enumerate, in lexicographic order, the positions in the arrays, then display the values at those positions:
#include <vector>
#include <iostream>
using std::vector;
void permutate(vector<vector<int>> values)
{
// the positions in each vector
vector<size_t> pos(values.size());
do
{
// display one of each array at current position
for(size_t i = 0; i < values.size(); ++i)
{
std::cout << values[i][pos[i]] << ", ";
}
std::cout << std::endl;
// increment the last array's display position
size_t p = 0;
pos[p]++;
// while we get to the end of current array, return to 0 and carry to next position
while(pos[p] == values[p].size())
{
pos[p] = 0;
p++;
pos[p]++;
// return when the last array's position get to its size
if (p == values.size())
{
return;
}
}
}
while(true);
}
int main()
{
vector<int> arr1 = {1, 3, 8};
vector<int> arr2 = {2, 9};
vector<int> arr3 = {1, 3, 9};
vector<vector<int>> allThree = {arr1, arr2, arr3};
permutate(allThree);
}
A good exercise, next, would be to template it so you accept std::vector<std::vector<T>>

C++ Array prints zeros before numbers and doesn't print 9

I'm trying to create a tic tac toe board but I'm having two problems. (Sorry if the format of this question is bad, this is my first time asking a question here)
#include <iostream>
#include <iomanip>
#include <cctype>
#include <fstream>
#include <cstdlib>
using namespace std;
One problem (the array declaration below) is that when the program runs (as shown at the very bottom), the last number (9) doesn't print it's just blank. If I replace the 9 with another number (for example, 5) it prints it out just like the other numbers. I can't figure out why it wont print for the number 9
char board[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int row;
int column;
void display_board();
int main()
{
display_board();
return 0;
}
void display_board()
{
for (row = 0; row < 3; row++)
{
for (column = 0; column < 3; column++)
{
cout << board[row][column];
}
cout << "\n";
}
}
The other problem is that when the program runs (as shown below), it prints three zeros before every number. I just want the 1-9 not the three zeros. I can't figure out why those three zeros are even there, let alone getting rid of them. Any and all help is appreciated thank you.
try
char board[3][3] = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
have fun coding, and try read some books on the way
Thank you for the help everyone.
It's true, the problem could be fixed by either putting the numbers in the array declaration in single quotes or by changing the array itself to an int. Silly mistake on my part. Thanks again.
Change
char board[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
to
int board[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
(Make your char array an integer array).
There is nothing else that seems to be wrong in your program. I just quickly ran it in an IDE and I am getting the desired output after changing the array to int.

Generate random enum without consecutive repetition

How do I generate random enum values without consecutive repetition?
enum keycode {
VK_LEFT = 75,
VK_UP = 72,
VK_RIGHT = 77,
VK_DOWN = 80
};
VK_LEFT, VK_DOWN, VK_UP, VK_RIGHT, VK_DOWN ...
and not
VK_LEFT, VK_DOWN, VK_UP, VK_UP, VK_RIGHT ...
Let's say your four values are 0, 1, 2, and 3.
Pick a random number N0 in {0, 1, 2, 3}.
Pick a random number N1 in {0, 1, 2, 3} \ {N0}.
Pick a random number N2 in {0, 1, 2, 3} \ {N1}.
Pick a random number N3 in {0, 1, 2, 3} \ {N2}.
And so on...
When you call the code that generates the random value from your enum, have it check the new random value against the last value selected. If they're equal, select another value.
This could be done in a while loop. Pseudocode:
keycode value;
while (value != lastChosen)
value = keycode[random.next];
lastChosen = value;
where lastChosen is the last selected value.
this will generate K non-repeating numbers between 1 and N:
vector<int> non_repeat(int K, int N)
{
vector<int> res;
int last = 1 + rand() % N;
res.push_back(last);
for(int i=1;i<K;++i)
{
int r = 1 + rand() % (N-1);
if(r>=last) ++r;
res.push_back(r);
last = r;
}
return res;
}
should be fairly easy to adopt to your need

Searching for specific groups using permutation without repetition and greedy aproach (homework)

I'm student of second year on CS. On my algorithms and data structures course I've been tasked with following problem:
Input:
2<=r<=20
2<=o<=10
0<=di<=100
Output:
number of combinations
or "NO" if there are none
r is number of integers
di are said integers
o is number of groups
I have to find the number of correct combinations. The correct combination is one where every integer is assigned to some group, none of the groups are empty and the sum of integers in every group is the same:
For an instance:
r = 4;
di = {5, 4, 5, 6}
o = 2;
So the sum of integers in every group should add up to 10:
5 + 4 + 5 + 6 = 20
20 / o = 20 / 2 = 10
So we can make following groups:
{5, 5}, {4, 6}
{5, 5}, {6, 4}
{5, 5}, {4, 6}
{5, 5}, {6, 5}
So as we can see, the every combination is essentialy same as first one.( The order of elements in group doesnt matter.)
So actually we have just one correct combination: {5, 5}, {4, 6}. Which means output is equal to one.
Other examples:
r = 4;
di = {10, 2, 8, 6}
o = 2;
10 + 2 + 8 + 6 = 26;
26 / o = 26 / 2 = 13
There is no way to make such a sum of these integers, so the output is "NO".
I had a following idea of getting this thing done:
struct Input { // holds data
int num; // number of integers
int groups; // number of groups
int sumPerGroup; // sum of integers per group
int *integers; // said integers
};
bool f(bool *t, int s) { // generates binary numbers (right to left"
int i = 0;
while (t[i]) i++;
t[i] = 1;
if (i >= s) return true;
if (!t[i + 1])
for (int j = i - 1; j >= 0; j--)
t[j] = 0;
return false;
}
void solve(Input *input, int &result) {
bool bin[input->num]; // holds generated binary numbers
bool used[input->num]; // integers already used
for (int i = 0; i < input->num; i++) {
bin[i] = 0;
used[i] = 0;
}
int solved = 0;
do {
int sum = 0;
for (int i = 0; i < input->num; i++) { // checking if generated combination gets me nice sum
if (sum > input->sumPerGroup) break;
if (bin[i] && !used[i]) sum += input->integers[i]; // if generated combination wasnt used before, start adding up
if (sum == input->sumPerGroup) { // if its add up as it shoul
for (int j = 0; j < input->num; j++) used[j] = bin[j]; // mark integers as used
solved ++; // and mark group as solved
sum = 0;
}
if (udane == input->groups) { // if the number of solved groups is equal to number of groups
result ++; // it means we found another correct combination
solved = 0;
}
}
} while (!f(bin, input->num)); // as long as I can get more combinations
}
So, the main idea is:
1. I generate combination of some numbers as binary number
2. I check if that combination gets me a nice sum
3. If it does, I mark that up
4. Rinse and repeat.
So for input from first example {5, 4, 5, 6} in 2 groups:
5 4 5 6
-------
0 0 0 0
1 0 0 0
...
1 0 1 0 -> this one is fine, becouse 5 + 5 = 10; I mark it as used
1 1 1 0
...
0 1 0 1 -> another one works (4 + 6 = 10); Marked as used
So far i got myself 2 working groups which is equal to 2 groups - job done, it's a correct combination.
The real problem behind my idea is that I have no way of using some integer once I mark it as "used". This way in more complicated examples I would miss quite alot of correct groups. My question is, what is correct approach to this kind of problem? I've tried recursive approach and it didin't work any better (for the same reason)
Another idea I had is to permutate (std:next_permutate(...) for instance) integers from input each time I mark some group as used, but even on paper that looks silly.
I don't ask you to solve that problem for me, but if you could point any flaws in my reasoning that would be terrific.
Also, not a native speaker. So I'd like to apologise in advance if I butchered any sentence (I know i did).