How could I express:
From Array[0-9][0-9] print Player
From Array[0-9][10-79] print blankSpace
From Array[10-19[0-29] print blankSpace
From Array[10-19][30-39] print tree1
Etc.
If it's not obvious I'm trying to print a game map where you can control the Player by moving it over "tiles" (Each one is equal to 10x10 of array positions or char spaces if you prefer) but I can't seem to find any way to "select" a range of positions in arrays instead of just two positions.
If I said [0][9] for player example it would print the player character on that one position but seeing as I'm printing in type char. it would only be equal to '!' for example. I'm meant to print a square of '!'s for example which would take up 10x10 chars.
Then using my logic, if I could "select" a range of array positions I could print out a pre-defined array of characters making up my overall character's look using the Player() function. Same for the blankSpaces and tree1 etc.
Any help/criticism/sarcastic banter on my fail logic would be appreciated.
Well, there's no built-in way to work with ranges quite the way you've described it, but there are loops, which come pretty close :-)
for (int j = 0; j != 10; ++j) {
for (int i = 0; i != 10; ++i) {
PrintPlayerAt(j, i);
}
}
It looks like you're going to end up "repainting" a whole rectangular region, though, and making the cursor jump around in (what I'm assuming is a console/command line) window is non-trivial. So I suggest changing your logic away from the object-oriented "print this *here*" to a locality-oriented "when we're here, print this. Some pseudo-code to clarify:
for (int j = 0; j != 20; ++j) {
for (int i = 0; i != 80; ++i) {
if ((0 <= j && j < 10) && (0 <= i && i < 10)) {
PrintPlayer();
}
else if ((10 <= j && j < 20) && (30 <= i && i < 40)) {
PrintTree();
}
// ...
else {
PrintBlankSpace();
}
}
}
Unfortunately there's no built-in way to do this in C++. You can use a nested loop to iterate across the array though.
Related
I'm making Sudoku validater program that checks whether solved sudoku is correct or not, In that program i need to compare multiple variables together to check whether they are equal or not...
I have provided a snippet of code, what i have tried, whether every su[][] has different value or not. I'm not getting expecting result...
I want to make sure that all the values in su[][] are unequal.
How can i achieve the same, what are mistakes in my snippet?
Thanks...
for(int i=0 ; i<9 ;++i){ //for checking a entire row
if(!(su[i][0]!=su[i][1]!=su[i][2]!=su[i][3]!=su[i][4]!=su[i][5]!=su[i][6]!=su[i][7]!=su[i][8])){
system("cls");
cout<<"SUDOKU'S SOLUTION IS INCORRECT!!";
exit(0);
}
}
To check for each column uniqueness like that you would have to compare each element to the other ones in a column.
e.g.:
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
for (int k = j + 1; k < 9; ++k) {
if (su[i][j] == su[i][k]) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
}
Since there are only 8 elements per row this cubic solution shouldn't give you much overhead.
If you had a higher number N of elements you could initialize an array of size N with 0 and transverse the column. For the i-th element in the column you add 1 to that elements position in the array. Then transverse the array. If there's a position whose value is different from 1, it means you have a duplicated value in the column.
e.g.:
for (int i = 0; i < N; ++i) {
int arr[N] = {0};
for (int j = 0; j < N; ++j)
++arr[su[i][j] - 1];
for (int i = 0; i < N; ++i) {
if (arr[i] != 1) {
system("cls");
cout << "SUDOKU'S SOLUTION IS INCORRECT!!\n";
exit(0);
}
}
}
This approach is way more faster than the first one for high values of N.
The codes above check the uniqueness for each column, you would still have to check for each row.
PS: I have not tested the codes, it may have a bug, but hope you get the idea.
Suppose I have a vector that contains n strings, where the strings can be length 5...n. Each string must be compared with each string character by character. If there is a mismatch, the score is increased by one. If there is a match, the score does not increase. Then I will store the resulting scores in a matrix.
I have implemented this in the following way:
for (auto i = 0u; i < vector.size(); ++i)
{
// vector.size() x vector.size() matrix
std::string first = vector[i]; //horrible naming convention
for (auto j = 0u; j < vector.size(); ++j)
{
std::string next = vector[j];
int score = 0;
for (auto k = 0u; k < sizeOfStrings; ++k)
{
if(first[k] == second[k])
{
score += 0;
}
else
{
score += 1;
}
}
//store score into matrix
}
}
I am not happy with this solution because it is O(n^3). So I have been trying to think of other ways to make this more efficient. I have thought about writing another function that would replace the innards of our j for loop, however, that would still be O(n^3) since the function would still need a k loop.
I have also thought about a queue, since I only care about string[0] compared to string[1] to string[n]. String[1] compared to string[2] to string[n]. String[2] compared to string[3] to string[n], etc. So my solutions have unnecessary computations since each string is comparing to every other string. The problem with this, is I am not really sure how to build my matrix out of this.
I have finally, looked into the std template library, however std::mismatch doesn't seem to be what I am looking for, or std::find. What other ideas do you guys have?
I don't think you can easily get away from O(n^3) comparisons, but you can easily implement the change you talk about. Since the comparisons only need to be done one way (i.e. comparing string[1] to string[2] is the same as comparing string[2] to string[1]), as you point out, you don't need to iterate through the entire array each time and can change the start value of your inner loop to be the current index of your outer loop:
for (auto i = 0u; i < vector.size(); ++i) {
// vector.size() x vector.size() matrix
std::string first = vector[i]; //horrible naming convention
for (auto j = i; j < vector.size(); ++j) {
To store it in a matrix, setup your i x j matrix, initialize it to all zeroes and simply store each score in M[i][j]
for (auto k = 0u; k < sizeOfStrings; ++k) {
if (first[k] != second[k]) {
M[i][j]++;
}
}
If you have n strings each of length m, then no matter what (even with your queue idea), you have to do at least (n-1)+(n-2)+...+(1)=n(n-1)/2 string comparisons, so you'll have to do (n(n-1)/2)*m char comparisons. So no matter what, your algorithm is going to be O(mn^2).
General comment:
You don't have to compare the same strings with each other. And what is more important you starting from the begining each time in second loop while you already computed those diffs, so change the second loop to start from i+1.
By doing so your complexity will decrease as you won't check string that you already checked or are the same.
Improvement
Sort vector and remove duplicated entries, then instead wasting computation for checking the same strings you will only check those that are different.
The other answers that say this is at least O(mn^2) or O(n^3) are incorrect. This can be done in O(mn) time where m is string size and n is number of strings.
For simplicity we'll start with the assumption that all characters are ascii.
You have a data structure:
int counts[m][255]
where counts[x][y] is the number of strings that have ascii character y at index x in the string.
Now, if you did not restrict to ascii, then you would need to use a std::map
map counts[m]
But it works the same way, at index m in counts you have a map in which each entry in the map y,z tells you how many strings z use character y at index m. You would also want to choose a map with constant time lookups and constant time insertions to match the complexity.
Going back to ascii and the array
int counts[m][255] // start by initializing this array to all zeros
First initialize the data structure:
m is size of strings,
vec is a std::vector with the strings
for (int i = 0; i < vec.size(); i++) {
std::string str = vec[i];
for(int j = 0; j < m; j++) {
counts[j][str[j]]++;
}
}
Now that you have this structure, you can calculate the scores easily:
for (int i = 0; i < vec.size(); i++) {
std::string str = vec[i];
int score = 0;
for(int j = 0; j < m; j++) {
score += counts[j][str[j]] - 1; //subtracting 1 gives how many other strings have that same char at that index
}
std::cout << "string \"" << str << "\" has score " << score;
}
As you can see by this code, this is O(m * n)
I have written this function that reverses the order of words within a string, the function behaves as expected until it has read two words then starts to behave unexpectedly:
string ReverseString(string InputString){
int EndOfGroup = 0;
string ReversedString = " ";
int k = 0;
ReversedString.resize(InputString.size());
for (int i = InputString.length(); i > 0; i--){
if (isspace(InputString[i]))
{
EndOfGroup = i;
for (int j = i; j >= EndOfGroup && j < InputString.length(); j++)
{
ReversedString[k] = InputString[j] ;
k++;
}
}
}
What I mean by behaves unexpectedly is that once I pass a string to the function it starts to populate the ReversedString variable with garbage values until the goes out of bounds.
This shoes the point the programme crashes:
InputString "the brown fox died"
ReversedString " died fox died brownÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ"
j 9
i 3
EndOfGroup 3
k 20
This is not a duplicate question as my method is different to existing methods out there.
Think about the inner loop,
for (int j = i; j >= EndOfGroup && j < InputString.length(); j++)
For the first word, this is good, now for the second word - are the conditions correct?
Remember you are writing to the reversed string using an incrementing index k...
You are copying the word only when you are meeting space sign
if (isspace(InputString[i]))
{
//start of copying...
what does mean that you will not copy the first work (there is no space before the word).
resize() method is fullfilling the string will null character (due to reference) and they are probably show as
ÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ
You need to handle the first word
for (int i = InputString.length(); i >= 0; i--){
if (isspace(InputString[i]) || i == 0)
Also it would be good to provide some default char instead of null by using
ReversedString.resize(InputString.size(), ' ');
I am having some trouble with my class project, essentially what I want to do is spawn objects randomly which so far is working perfectly, they are spawned from an 2d array that stores X and Z which have been randomly generated within reasonable distance. The issue I am having is objects being placed inside each other due to lack of duplicate detection. I need to go through the 2d array, see if any X and Y co-ords match and randomize any matches found. Sorry if this doesn't make a lot of sense, i'm not too good at explaining things but perhaps you could take a look at my current detection method and give me some tips?
for (int k = 0; k <= NumofShrooms - 1; k++)
{
for (int i = 0; i <= NumofShrooms - 1;)
{
if (k == i)
{
i++;
}
if (SpawnArray[k][2] == SpawnArray[i][2])
{
SpawnArray[k][2] = rand() % 16 + 1;
i = 0;
}
else i++;
}
}
The following function takes three word objects and checks each word's letter coordinates (in a table) against each other. The idea is to get combinations of three words from a list that don't have intersecting letter coordinates. However when you have over 600000 possible combinations this becomes very time consuming.
bool lettersIntersect(word one, word two, word three)
{
for(int i = 0; i < one.getLength(); i++)
for(int j = 0; j < two.getLength(); j++)
if(one.getLetterPosition(i).x == two.getLetterPosition(j).x && one.getLetterPosition(i).y == two.getLetterPosition(j).y)
return true;
for(int i = 0; i < two.getLength(); i++)
for(int j = 0; j < three.getLength(); j++)
if(two.getLetterPosition(i).x == three.getLetterPosition(j).x && two.getLetterPosition(i).y == three.getLetterPosition(j).y)
return true;
for(int i = 0; i < three.getLength(); i++)
for(int j = 0; j < one.getLength(); j++)
if(three.getLetterPosition(i).x == one.getLetterPosition(j).x && three.getLetterPosition(i).y == one.getLetterPosition(j).y)
return true;
return false;
}
Is there a more efficient way of doing this?
I can just give you 1 hint which striked me instantly. Don't blame me if its misleading. You can just try once at your end and see the performance.
Create map (use stl) for each word objects i.e. map_one, map_two, and map_three
Add co-ordinate value as key for each letter of a given word object to its respective map.
Then check using these maps whether there is an intersection.
Check if map in C++ contains all the keys from another map
The only thing I see possible to optimize is avoiding double checks:
for(int i = 0; i < one.getLength(); i++)
for(int j = i+1; j < two.getLength(); j++)
if(one.getLetterPosition(i).x == two.getLetterPosition(j).x && one.getLetterPosition(i).y == two.getLetterPosition(j).y)
return true;
The second for loop was changed from j = 0, to j = i+1, which makes you do the checks in half the time.
Checking between two coordinates points is a n^2 (n-square) problem, which means that the time required to do the checks is proportional to square the number of elements you can check. I thikn there's no other way to optimize this other than avoiding double checks, like I explained.
Of course, in addition to passing by references, like was suggested to you already.
On this homework problem or other learning exercise, you are intended to use a method you have been taught previously that rearranges data to make searching faster. Having rearranged the data, you should be able to find a way to scan it efficiently to find duplicates.