C++ function not found during compilation - c++
For a homework assignment: I'm supposed to create randomized alphabetial keys, print them to a file, and then hash each of them into a hash table using the function "goodHash", found in my below code.
When I try to run the below code, it says my "goodHash" "identifier isn't found". What's wrong with my code?
#include <iostream>
#include <vector>
#include <cstdlib>
#include "math.h"
#include <fstream>
#include <time.h>
using namespace std;
// "makeKey" function to create an alphabetical key
// based on 8 randomized numbers 0 - 25.
string makeKey() {
int k;
string key = "";
for (k = 0; k < 8; k++) {
int keyNumber = (rand() % 25);
if (keyNumber == 0)
key.append("A");
if (keyNumber == 1)
key.append("B");
if (keyNumber == 2)
key.append("C");
if (keyNumber == 3)
key.append("D");
if (keyNumber == 4)
key.append("E");
if (keyNumber == 5)
key.append("F");
if (keyNumber == 6)
key.append("G");
if (keyNumber == 7)
key.append("H");
if (keyNumber == 8)
key.append("I");
if (keyNumber == 9)
key.append("J");
if (keyNumber == 10)
key.append("K");
if (keyNumber == 11)
key.append("L");
if (keyNumber == 12)
key.append("M");
if (keyNumber == 13)
key.append("N");
if (keyNumber == 14)
key.append("O");
if (keyNumber == 15)
key.append("P");
if (keyNumber == 16)
key.append("Q");
if (keyNumber == 17)
key.append("R");
if (keyNumber == 18)
key.append("S");
if (keyNumber == 19)
key.append("T");
if (keyNumber == 20)
key.append("U");
if (keyNumber == 21)
key.append("V");
if (keyNumber == 22)
key.append("W");
if (keyNumber == 23)
key.append("X");
if (keyNumber == 24)
key.append("Y");
if (keyNumber == 25)
key.append("Z");
}
return key;
}
// "makeFile" function to produce the desired text file.
// Note this only works as intended if you include the ".txt" extension,
// and that a file of the same name doesn't already exist.
void makeFile(string fileName, int n) {
ofstream ourFile;
ourFile.open(fileName);
int k; // For use in below loop to compare with n.
int l; // For use in the loop inside the below loop.
string keyToPassTogoodHash = "";
for (k = 1; k <= n; k++) {
for (l = 0; l < 8; l++) { // For-loop to write to the file ONE key
ourFile << makeKey()[l];
keyToPassTogoodHash += (makeKey()[l]);
}
ourFile << " " << k << "\n";// Writes two spaces and the data value
goodHash(keyToPassTogoodHash); // I think this has to do with the problem
makeKey(); // Call again to make a new key.
}
}
// Primary function to create our desired file!
void mainFunction(string fileName, int n) {
makeKey();
makeFile(fileName, n);
}
// Hash Table for Part 2
struct Node {
int key;
string value;
Node* next;
};
const int hashTableSize = 10;
Node* hashTable[hashTableSize];
// "goodHash" function for Part 2
void goodHash(string key) {
int x = 0;
int y;
int keyConvertedToNumber = 0;
// For-loop to produce a numeric value based on the alphabetic key,
// which is then hashed into hashTable using the hash function
// declared below the loop (hashFunction).
for (y = 0; y < 8; y++) {
if (key[y] == 'A' || 'B' || 'C')
x = 0;
if (key[y] == 'D' || 'E' || 'F')
x = 1;
if (key[y] == 'G' || 'H' || 'I')
x = 2;
if (key[y] == 'J' || 'K' || 'L')
x = 3;
if (key[y] == 'M' || 'N' || 'O')
x = 4;
if (key[y] == 'P' || 'Q' || 'R')
x = 5;
if (key[y] == 'S' || 'T')
x = 6;
if (key[y] == 'U' || 'V')
x = 7;
if (key[y] == 'W' || 'X')
x = 8;
if (key[y] == 'Y' || 'Z')
x = 9;
keyConvertedToNumber = x + keyConvertedToNumber;
}
int hashFunction = keyConvertedToNumber % hashTableSize;
Node *temp;
temp = new Node;
temp->value = key;
temp->next = hashTable[hashFunction];
hashTable[hashFunction] = temp;
}
// First two lines are for Part 1, to call the functions key to Part 1.
int main() {
srand ( time(NULL) ); // To make sure our randomization works.
mainFunction("sandwich.txt", 5); // To test program
cin.get();
return 0;
}
I realize my code is cumbersome in some sections, but I'm a noob at C++ and don't know much to do it better.
I'm guessing another way I could do it is to AFTER writing the alphabetical keys to the file, read them from the file and hash each key as I do that, but I wouldn't know how to go about coding that.
C++ expected everything to be declared in order, so that nothing's used before it's declared.
If you need to refer to a function higher in the file than where it's defined, you need to have a function prototype near the top of the file that declares the function. (Writing prototypes for all functions is a standard practice as a result of this.)
Near the top of the file (after the #includes) simply add
void goodHash(string key);
Definitions
Function declaration: something that declares the name of the function and the types the function takes.
Function definition: something that specifies the actual code of the function.
if you insert
void goodHash(string key);
in the line under "using namespace..." it will work
The issue is that you have to forward declare goodHash or define goodHash before makeFile if you want to use goodHash in makeFile. Otherwise, when the compile is in makeFile, it sees the token goodHash and hasn't found out what it means, which is why you are getting the compile-time error.
EDIT: Here is a good resource on forward declarations
you forgot the function prototype just add this in the top:
void goodHash(string key);
and btw your makeKey() is too long
you can try this instead:
string makeKey() {
int k;
string key = "";
for (k = 0; k < 8; k++) {
int keyNumber = (rand() % 25);
char app[2];
app[0] = keyNumber + 'A';
app[1] = 0;
key.append(app);
}
return key;
}
Related
Stack smashing detected
#include <iostream> using namespace std; int main() { int tablica[9]; string inputromanum; cout << "ROMAN: "; cin >> inputromanum; int maxindeks; bool disablenextcomp = false; int readysolution = 0; maxindeks = inputromanum.length() - 1;{}{} for (int i = 0; i <= maxindeks; i++) { if (inputromanum[i] == 'M' || inputromanum[i] == 'm') { tablica[i] = 1000; } if (inputromanum[i] == 'D' || inputromanum[i] == 'd') { tablica[i] = 500; } if (inputromanum[i] == 'C'|| inputromanum[i] == 'c') { tablica[i] = 100; } if (inputromanum[i] == 'L' || inputromanum[i] == 'l') { tablica[i] = 50; } if (inputromanum[i] == 'X' || inputromanum[i] == 'x') { tablica[i] = 10; } if (inputromanum[i] == 'V' || inputromanum[i] == 'v') { tablica[i] = 5; } if (inputromanum[i] == 'I' || inputromanum[i] == 'i') { tablica[i] = 1; } } cout<<endl; for(int i4 = 0; i4 <= maxindeks; i4++) { cout<<"tablica["<<i4<<"] = "<<tablica[i4]<<endl; } for (int i2 = 0; i2 <= maxindeks; i2++) { int i5 = i2 + 1; if (i5 <= maxindeks) { //cout<<endl<<"tablica[i2 + 1] = "<<tablica[i2 + 1]; //cout<<endl<<"tablica[i2] = "<<tablica[i2]; //cout<<endl<<"tablica[i2 + 1] - tablica[i2] = "<<tablica[i2 + 1] - tablica[i2]; if (tablica[i2 + 1] - tablica[i2] > 0 && disablenextcomp == false) { //cout<<endl<<"readysolution + (tablica[i2 + 1] - tablica[i2]) = "<<readysolution + (tablica[i2 + 1] - tablica[i2])<<endl; readysolution = readysolution + (tablica[i2 + 1] - tablica[i2]); disablenextcomp = true; } else { if(disablenextcomp == false) { //cout<<endl<<"readysolution + tablica[i2] = "<<readysolution + tablica[i2]<<endl; readysolution = readysolution + tablica[i2]; } else { disablenextcomp = false; } } } else { if(disablenextcomp == false) { //cout<<endl<<endl<<"OSTATNI INDEKS"; //cout<<endl<<"tablica[i2] = "<<tablica[i2]; //cout<<endl<<"readysolution + tablica[i2] = "<<readysolution + tablica[i2]; readysolution = readysolution + tablica[i2]; } } i5++; } cout << endl << readysolution; } This is my program. made for decoding roman numerals into arabic ones. It works as intended in most cases, however, one of my colleagues found it to produce this error while inputting MMMCMXCVIII into the program: *** stack smashing detected ***: terminated It would refuse to work afterwards. I wasn't able to find different numbers that would cause this error except MMMMMMMMMMM. It seems to fail when the index of tablica array exceeds 10. I don't know why it does so, as i am a novice in c++. It should've outputted 3999 instead of the error appearing. The numbers it should process successfully should range from 1 to 5000.
Thanks to folks in the comments, I've found the cause. The tablica[9] array is supposed to store 9 or less characters. The length of the input (MMMCMXCVIII in this case) has more characters, therefore it makes the for loop responsible for storing values for each character to cause mentioned above error, as there are no remaining units to store the values in. I've expanded the storage of tablica to 25 characters.
In modern C++ it is considered bad practice to use C-style arrays and index loops whenever you can avoid this. So, fo example you can rewrite first loop like this: std::vector<int> tablica; tablica.reserve(inputromanum.size()); // This line is not necessary, but it can help optimize memory allocations for (char c : inputromanum) { if (c == 'M' || c == 'm') { tablica.push_back(1000); } if (c == 'D' || c == 'd') { tablica.push_back(500); } if (c == 'C'|| c == 'c') { tablica.push_back(100); } if (c == 'L' || c == 'l') { tablica.push_back(50); } if (c == 'X' || c == 'x') { tablica.push_back(10); } if (c == 'V' || c == 'v') { tablica.push_back(5); } if (c == 'I' || c == 'i') { tablica.push_back(1); } } And you will avoid your issue completly. Something similar can be done with other loops too. This approach also has benefit of (somewhat) properly handling situations when input line has other symbols, which is not roman number. Try it on your version and you will see what I mean. One more point. When you need to do something different depending of value of one variable, like you did with all those ifs. There is special statement in C/C++ for this: switch. So instead of those ifs you can do this: std::vector<int> tablica; tablica.reserve(inputromanum.size()); // This line is not necessary, but it can help optimize memory allocations for (char c : inputromanum) { switch(c) { case 'M': case 'm': tablica.push_back(1000); break; case 'D': case 'd': tablica.push_back(500); break; case 'C': case 'c': tablica.push_back(100); break; case 'L': case 'l': tablica.push_back(50); break; case 'X': case 'x': tablica.push_back(10); break; case 'V': case 'v': tablica.push_back(5); break; case 'I': case 'i': tablica.push_back(1); break; } }
Why is this c++ code producing weird characters?
I wanted to simplify algebraic expressions in c++. I started with something simple: removing brackets from a algebraic expression containing + and - operators. For example, a-(b-c) should be simplified to a-b+c. This link gives the answer to this question. Here is the source code: #include <iostream> #include <string.h> #include <stack> using namespace std; // Function to simplify the string char* simplify(string str) { int len = str.length(); // resultant string of max length equal // to length of input string char* res = new char(len); int index = 0, i = 0; // create empty stack stack<int> s; s.push(0); while (i < len) { if (str[i] == '+') { // If top is 1, flip the operator if (s.top() == 1) res[index++] = '-'; // If top is 0, append the same operator if (s.top() == 0) res[index++] = '+'; } else if (str[i] == '-') { if (s.top() == 1) res[index++] = '+'; else if (s.top() == 0) res[index++] = '-'; } else if (str[i] == '(' && i > 0) { if (str[i - 1] == '-') { // x is opposite to the top of stack int x = (s.top() == 1) ? 0 : 1; s.push(x); } // push value equal to top of the stack else if (str[i - 1] == '+') s.push(s.top()); } // If closing parentheses pop the stack once else if (str[i] == ')') s.pop(); // copy the character to the result else res[index++] = str[i]; i++; } return res; } I tested the function on a-(b-c-(d+e))-f and it gave the result a-b+c+d+e-fÿï┌. Why is it producing weird characters?
How to obtain the whole integers from file has strings and integers and store them into array in C++?
I want to obtain integers from file that has strings too, and store them into array to do some operation on them. the integers can be 1 or 12 or 234, so 3 digits. I am trying to do that but the output stops when I run the code void GetNumFromFile (ifstream &file1, char & contents) { int digits[20]; file1.get(contents); while(!file1.eof()) { for (int n = 0; n < 10; n++) { if(('0' <= contents && contents <= '9') && ('0' >= contents+1 && contents+1 > '9')); digits[n]=contents; if(('0' <= contents && contents <= '9') && ('0' <= contents+1 && contents+1 < '9')); digits[n]=contents; if(('0' <= contents && contents <= '9') && ('0' <= contents+1 && contents+1 <= '9') && ('0' <= contents+2 && contents+2 < '9')); digits[n]=contents; } continue; } for (int i = 0; i <= 20; i++) { cout << *(digits + i) << endl; } }
You have to deal with the number of digits of the number found: int digits[20]; int i = 0; short int aux[3]; // to format each digit of the numbers ifstream file1("filepath"); char contents; file1.get(contents); //first char if (!file1.eof()) //test if you have only one char in the file { while (!file1.eof() && i < 20) // limit added to read only 20 numbers { if (contents <= '9' && contents >= '0') // if character is in number range { aux[0] = contents - '0'; // converting the char to the right integer file1.get(contents); if (contents <= '9' && contents >= '0') // if contents is number, continue on { aux[1] = contents - '0'; if (!file1.eof()) // if has mor char to read, continue on { file1.get(contents); if (contents <= '9' && contents >= '0') // if is integer, continue on { aux[2] = contents - '0'; file1.get(contents); // will read same of last char if eof, but will have no effect at all //aux[0] *= 100; // define houndred //aux[1] *= 10; // define ten digits[i++] = (aux[0] * 100) + (aux[1] * 10) + aux[2]; } else { //aux[0] *= 10; // define ten digits[i++] = (aux[0] * 10) + aux[1]; } } else { digits[i++] = (aux[0] * 10) + aux[1]; } } else { digits[i++] = aux[0]; } } } } else if (contents <= '9' && contents >= '0' && i < 20) // check if the only one char is number { digits[i++} = contents - '0'; } If you want read an undefined size number, then you will have to allocate memory to format each digit of the numers with new (c++) or malloc(c/c++).
First observation: you iterate out of bounds of the array: int digits[20]; for (int i = 0; i <= 20; i++) 20 elements and 21 iteration. That is an undefined behavior, so everything is possible here (if your program eventually gets here). Next, you read from file once and then you have an infinite loop because the expression !file1.eof() is either true or false for the rest of the program run. Isn't that the reason of "output stops"? The third finding: your if statements are useless because of the semicolon after the statement: if(('0' <= contents && contents <= '9') && ('0' >= contents+1 && contents+1 > '9')); digits[n]=contents; You just assign digits[n]=contents; without any check. I neither see any reason of providing a reference to char in the function. Why not to make it a local variable?
You will need first to add get() functionality inside the loop as well in order to reach end of file. Forthmore try to add a while loop once a char was found to be an integer to continue in asking for the next character. e.g. int digits[20]; int i = 0; ifstream file1("filepath"); char contents; while (!file1.eof()) { file1.get(contents); // get the next character if (contents <= '9' && contents >= '0' && i < 20) // if character is in number range { digits[i++] = contents - '0'; // converting the chat to the right integer file1.get(contents); while (contents <= '9' && contents >= '0' && i < 20) // while is integer continue on { digits[i++] = contents - '0'; file1.get(contents); } } } // do other stuff here
Sudoku solving algorithm C++
I'm trying to make a Sudoku Solving program for a couple of days but I'm stuck with the methods. I found this algorithm here but I don't really understand it: start at the first empty cell, and put 1 in it. Check the entire board, and see if there are any conflicts If there are coflicts on the board, increase the number in the current cell by 1 (so change 1 to 2, 2 to 3, etc) If the board is clean move, start at step one again. If all nine possible numbers on a given cell cause a conflict in the board, then you set this cell back to empty, go back to the previous cell, and start again from step 3 (this is where the 'backtracking' comes in). Here is my code. I think something is wrong with my Help_Solve(...) function. Can you help me to identify the problem, please? #include <iostream> #include <iomanip> #include <time.h> #include <cstdlib> #include <windows.h> using namespace std; class Sudoku { private: int board[9][9]; int change[9][9]; public: Sudoku(); void Print_Board(); void Add_First_Cord(); void Solve(); void Help_Solve(int i, int j); bool Check_Conflicts(int p, int i, int j); }; Sudoku Game; void setcolor(unsigned short color) //The function that you'll use to { //set the colour HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hcon,color); } Sudoku::Sudoku() { for(int i = 1; i <= 9; i++) for(int j = 1; j <= 9; j++) board[i][j] = 0; } void Sudoku::Print_Board() { for(int i = 1; i <= 9; i++) { for(int j = 1; j <= 9; j++) { if(change[i][j] == 1) { setcolor(12); cout << board[i][j] << " "; setcolor(7); } else cout << board[i][j] << " "; if(j%3 == 0) cout << "| "; } cout << endl; if(i%3 == 0) cout << "------+-------+---------" << endl; } } void Sudoku::Add_First_Cord() { board[1][1] = 5; change[1][1] = 1; board[1][2] = 3; change[1][2] = 1; board[1][5] = 7; change[1][5] = 1; board[2][1] = 6; change[2][1] = 1; board[2][4] = 1; change[2][4] = 1; board[2][5] = 9; change[2][5] = 1; board[2][6] = 5; change[2][6] = 1; board[3][2] = 9; change[3][2] = 1; board[3][3] = 8; change[3][3] = 1; board[3][8] = 6; change[3][8] = 1; board[4][1] = 8; change[4][1] = 1; board[4][5] = 6; change[4][5] = 1; board[4][9] = 3; change[4][9] = 1; board[5][1] = 4; change[5][1] = 1; board[5][4] = 8; change[5][4] = 1; board[5][6] = 3; change[5][6] = 1; board[5][9] = 1; change[5][9] = 1; board[6][1] = 7; change[6][1] = 1; board[6][5] = 2; change[6][5] = 1; board[6][9] = 6; change[6][9] = 1; board[7][2] = 6; change[7][2] = 1; board[7][7] = 2; change[7][7] = 1; board[7][8] = 8; change[7][8] = 1; board[8][4] = 4; change[8][4] = 1; board[8][5] = 1; change[8][5] = 1; board[8][6] = 9; change[8][6] = 1; board[8][9] = 5; change[8][9] = 1; board[9][5] = 8; change[9][5] = 1; board[9][8] = 7; change[9][8] = 1; board[9][9] = 9; change[9][9] = 1; } bool Sudoku::Check_Conflicts(int p, int i, int j) { for(int k = 1; k <= 9; k++) if(board[i][k] == p) return false; for(int q = 1; q <= 9; q++) if(board[q][j] == p) return false; /* *00 000 000 */ if((j == 1 || j == 4 || j == 7) && (i == 1 || i == 4 || i == 7)) { if(board[i][j+1] == p || board[i][j+2] == p || board[i+1][j] == p || board[i+2][j] == p || board[i+1][j+1] == p || board[i+1][j+2] == p || board[i+2][j+1] == p || board[i+2][j+2] == p)return false; } /* 000 000 *00 */ if((j == 1 || j == 4 || j == 7) && (i == 3 || i == 6 || i == 9)) { if(board[i-1][j] == p || board[i-2][j] == p || board[i][j+1] == p || board[i][j+2] == p || board[i-1][j+1] == p || board[i-1][j+2] == p || board[i-2][j+1] == p || board[i-2][j+2] == p)return false; } /* 000 *00 000 */ if((j == 1 || j == 4 || j == 7) && (i == 2 || i == 5 || i == 8)) { if(board[i-1][j] == p || board[i+1][j] == p || board[i-1][j+1] == p || board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j+2] == p || board[i][j+2] == p || board[i+1][j+2] == p)return false; } /* 0*0 000 000 */ if((j == 2 || j == 5 || j == 8) && (i == 1 || i == 5 || i == 7)) { if(board[i-1][j] == p || board[i+1][j] == p || board[i-1][j+1] == p || board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j+2] == p || board[i][j+2] == p || board[i+1][j+2] == p)return false; } /* 000 0*0 000 */ if((j == 2 || j == 5 || j == 8) && (i == 2 || i == 5 || i == 8)) { if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j+1] == p || board[i][j+1] == p || board[i][j-1] == p || board[i+1][j+1] == p || board[i][j] == p || board[i+1][j-1] == p)return false; } /* 000 000 0*0 */ if((j == 2 || j == 5 || j == 8) && (i == 3 || i == 6 || i == 9)) { if(board[i][j-1] == p || board[i][j+1] == p || board[i-1][j] == p || board[i-1][j+1] == p || board[i-1][j-1] == p || board[i-2][j] == p || board[i-1][j+1] == p || board[i-2][j-1] == p) return false; } /* 00* 000 000 */ if((j == 3 || j == 6 || j == 9) && (i == 1 || i == 4 || i == 7)) { if(board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p || board[i+1][j-1] == p || board[i+1][j-2] == p || board[i+2][j] == p || board[i+2][j-1] == p || board[i+2][j-2] == p) return false; } /* 000 00* 000 */ if((j == 3 || j == 6 || j == 9) && (i == 2 || i == 5 || i == 8)) { if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j-2] == p || board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p || board[i+1][j-1] == p || board[i+1][j-2] == p) return false; } /* 000 000 00* */ if((j == 3 || j == 6 || j == 9) && (i == 3 || i == 6 || i == 9)) { if(board[i][j-1] == p || board[i][j-1] == p || board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j-2] == p || board[i-2][j] == p || board[i-2][j-1] == p || board[i-2][j-2] == p) return false; } return true; } void Sudoku::Help_Solve(int i, int j) { if(j <= 0) { i = i-1; j = 9; } if(change[i][j] == 1) return Game.Help_Solve(i, j-1); for(int p = 1; p <= 9; p++) if(Game.Check_Conflicts(p, i, j)) { board[i][j] = p; return; } return Game.Help_Solve(i, j-1); } void Sudoku::Solve() { for(int i = 1; i <= 9; i++) { for(int j = 1; j <= 9; j++) { if(board[i][j] == 0 && change[i][j] == 0) { Game.Help_Solve(i, j); } } } for(int i = 1; i <= 9; i++) for(int j = 1; j <= 9; j++) if(board[i][j] == 0) Game.Help_Solve(i, j); } int main() { Game.Add_First_Cord(); Game.Solve(); Game.Print_Board(); system("pause"); return 0; } Edit: I need to use recursion right? But maybe the parameters I give to the function are wrong. I really don't know. In Add_First_Cord() I declare the starting values that every sudoku has in the beginning. Here are the values that I use: http://bg.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:Sudoku-by-L2G-20050714.gif. I expect to see the solved sudoku as it is shown in wikipedia. But some solved values are right others are not. Here is what I get in the console
Suggested Approach Implement a generic graph search algorithm could use either IDFS or A* graph search I would prefer the second do this for a general directed graph node type TNode node successor function TNode => vector<TNode> Define your Sudoku states a state is a 9x9 array with a number 1, 2, ..., or 9 or a blank in each position Define what a goal Sudoku state is all 81 cells filled in all 9 rows have numbers {1, 2, ..., 9} in them all 9 columns have numbers {1, 2, ..., 9} in them all 9 3x3 squares have numbers {1, 2, ..., 9} in them Define your valid Sudoku state successor function a state S can have number N added at row I, column J if: cell (I,J) is empty there is no other N in row I there is no other N in column J there is no other N in the 3x3 square containing (I,J) the state successor function maps a state S to the vector of states that satisfy these rules Apply your generic graph search algorithm (1) to the Sudoku state graph (2-4) (optional) If you do choose to use A* graph search, you can also define a heuristic on your Sudoku state space to potentially drastically increase performance how to design the heuristic is another whole problem, that's more of an art than a science Current Approach Your current approach mixes the specification of the graph to be searched and the implementation of the search algorithm. You're going to have a lot of difficulty if you mix those two. This problem naturally separates into two distinct pieces -- the algorithm and the graph -- so you can and should exploit that in your implementation. It will make it much simpler. The other benefit you get if you go with this separation is that you will be able to reuse your graph search algorithm on a huge number of problems - very cool!
The following assumes you are trying to solve a given board, not generate a puzzle. Basic (simple) approach Create a class whose objects can hold a board (here called board_t). This class may internally use array, but must support copying boards. Have a function void solve(board_t const& board); which repeats the following for each number n: Copies your input Enters n in the first empty cell of the copied board If the copied board is a solution, print the solution and return. Else If the board is still viable (e.g. no conflicts): call solve(copied_board) Performance This is a recursive backtracking solution, which performs horribly for hard problems. You can significantly speed it up by proper pruning or deductive steps (e.g. if you end up with 8 numbers in a row after inserting one, you can immediately enter the ninth without any kind of search). Reasoning While certainly not an impressive technique, it has a high probability of working correctly, since you will only ever be modifying a copy to add a single value. This prevents corruption of your data structures (one problem your idea has is that it will destroy the numbers it finds when backtracking, are not necessarily the ones you just inserted, but may be part of the initial puzzle). Improving performance is quite simple, once you start picking more intelligent heuristics (e.g. instead of testing the square in order, you could pick the ones with the fewest remaining moves and try to get them out of the way - or do the reverse...) or start doing a bit of deduction and pruning. Note: The Algorithm Design Manual uses a Soduko solver to show the impact of these techniques on backtracking.
There is one very important modification to recursive algorithms: Use most constrained first approach. This means first to solve a cell with smallest number of possible candidates (when direct row/column/block conflicts are removed). Another modification is: Change the board in-place; do not copy it. In each recursive call you modify only one cell on the board, and that cell used to be empty. If that call doesn't end up in a solved board somewhere down the recursive call tree, just clear the cell again before returning - this returns the board into original state. You can find a very short and fast solution in C# on address: Sudoku Solver. It solves arbitrary sudoku board in about 100 steps only, all thanks to the most constrained first heuristic.
This is a classic Constraint Satisfaction Problem. I recommend doing some research on the topic to figure out the successful strategy. You will need to use AC-3 ( Arc Consistency 3) algorithm along with the backtracking techniques to solve the problem.
C/C++ URL decode library
I am developing a c/c++ program on linux. Can you please tell me if there is any c/c++ library which decodes url? I am looking for libraries which convert "http%3A%2F%2F" to: "http://" or "a+t+%26+t" to "a t & t" Thank you.
I actually used Saul's function in an analysis program I was writing (analyzing millions of URL encoded strings), and while it works, at that scale it was slowing my program down horribly, so I decided to write a faster version. This one is thousands of times faster when compiled with GCC and the -O2 option. It can also use the same output buffer as the input (e.g. urldecode2(buf, buf) will work if the original string was in buf and is to be overwritten by its decoded counterpart). Edit: It doesn't take the buffer size as an input because it is assumed that the buffer will be large enough, this is safe because it is known that the length of the output will always be <= that of the input, so either use the same buffer for the output or create one that's at least the size of the input + 1 for the null terminator, e.g.: char *output = malloc(strlen(input)+1); urldecode2(output, input); printf("Decoded string: %s\n", output); Edit 2: An anonymous user attempted to edit this answer to handle the '+' character's translation to ' ', which I think it should probably do, again this wasn't something that I needed for my application, but I've added it below. Here's the routine: #include <stdlib.h> #include <ctype.h> void urldecode2(char *dst, const char *src) { char a, b; while (*src) { if ((*src == '%') && ((a = src[1]) && (b = src[2])) && (isxdigit(a) && isxdigit(b))) { if (a >= 'a') a -= 'a'-'A'; if (a >= 'A') a -= ('A' - 10); else a -= '0'; if (b >= 'a') b -= 'a'-'A'; if (b >= 'A') b -= ('A' - 10); else b -= '0'; *dst++ = 16*a+b; src+=3; } else if (*src == '+') { *dst++ = ' '; src++; } else { *dst++ = *src++; } } *dst++ = '\0'; }
Here is a C decoder for a percent encoded string. It returns -1 if the encoding is invalid and 0 otherwise. The decoded string is stored in out. I'm quite sure this is the fastest code of the answers given so far. int percent_decode(char* out, const char* in) { { static const char tbl[256] = { -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, -1,10,11,12,13,14,15,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,10,11,12,13,14,15,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1 }; char c, v1, v2, *beg=out; if(in != NULL) { while((c=*in++) != '\0') { if(c == '%') { if((v1=tbl[(unsigned char)*in++])<0 || (v2=tbl[(unsigned char)*in++])<0) { *beg = '\0'; return -1; } c = (v1<<4)|v2; } *out++ = c; } } *out = '\0'; return 0; }
uriparser library is small and lightweight.
This function I've just whipped up is very lightweight and should do as you wish, note I haven't programmed this to strict URI standards (used what I know off the top of my head). It's buffer-safe and doesn't overflow as far as I can see; adapt as you deem fit: #include <assert.h> void urldecode(char *pszDecodedOut, size_t nBufferSize, const char *pszEncodedIn) { memset(pszDecodedOut, 0, nBufferSize); enum DecodeState_e { STATE_SEARCH = 0, ///< searching for an ampersand to convert STATE_CONVERTING, ///< convert the two proceeding characters from hex }; DecodeState_e state = STATE_SEARCH; for(unsigned int i = 0; i < strlen(pszEncodedIn)-1; ++i) { switch(state) { case STATE_SEARCH: { if(pszEncodedIn[i] != '%') { strncat(pszDecodedOut, &pszEncodedIn[i], 1); assert(strlen(pszDecodedOut) < nBufferSize); break; } // We are now converting state = STATE_CONVERTING; } break; case STATE_CONVERTING: { // Conversion complete (i.e. don't convert again next iter) state = STATE_SEARCH; // Create a buffer to hold the hex. For example, if %20, this // buffer would hold 20 (in ASCII) char pszTempNumBuf[3] = {0}; strncpy(pszTempNumBuf, &pszEncodedIn[i], 2); // Ensure both characters are hexadecimal bool bBothDigits = true; for(int j = 0; j < 2; ++j) { if(!isxdigit(pszTempNumBuf[j])) bBothDigits = false; } if(!bBothDigits) break; // Convert two hexadecimal characters into one character int nAsciiCharacter; sscanf(pszTempNumBuf, "%x", &nAsciiCharacter); // Ensure we aren't going to overflow assert(strlen(pszDecodedOut) < nBufferSize); // Concatenate this character onto the output strncat(pszDecodedOut, (char*)&nAsciiCharacter, 1); // Skip the next character i++; } break; } } }
The ever-excellent glib has some URI functions, including scheme-extraction, escaping and un-escaping.
I'd suggest curl and libcurl. It's widely used and should do the trick for you. Just check their website.
Thanks to #ThomasH for his answer. I'd like to propose here a better formattation… And… since the decoded URI component is always less long than the same encoded URI component, is always possible to implode it within the same array of characters (a.k.a.: "string"). So, I'll propose here two possibilities: #include <stdio.h> #include <ctype.h> #include <limits.h> int decodeURIComponent (char *sSource, char *sDest) { int nLength; for (nLength = 0; *sSource; nLength++) { if (*sSource == '%' && sSource[1] && sSource[2] && isxdigit(sSource[1]) && isxdigit(sSource[2])) { sSource[1] -= sSource[1] <= '9' ? '0' : (sSource[1] <= 'F' ? 'A' : 'a')-10; sSource[2] -= sSource[2] <= '9' ? '0' : (sSource[2] <= 'F' ? 'A' : 'a')-10; sDest[nLength] = 16 * sSource[1] + sSource[2]; sSource += 3; continue; } sDest[nLength] = *sSource++; } sDest[nLength] = '\0'; return nLength; } #define implodeURIComponent(url) decodeURIComponent(url, url) And, finally…: int main () { char sMyUrl[] = "http%3a%2F%2ffoo+bar%2fabcd"; int nNewLength = implodeURIComponent(sMyUrl); /* Let's print: "http://foo+bar/abcd\nLength: 19" */ printf("%s\nLength: %d\n", sMyUrl, nNewLength); return 0; } Ste*
Try urlcpp https://github.com/larroy/urlcpp It's a C++ module that you can easily integrate in your project, depends on boost::regex
Came across this 8 year old question as I was looking for the same. Based on previous answers, I also wrote my own version which is independent from libs, easy to understand and probably fast (no benchmark). Tested code with gcc, it should decode until end or invalid character (not tested). Just remember to free allocated space. const char ascii_hex_4bit[23] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15}; static inline char to_upper(char c) { if ((c >= 'a') && (c <= 'z')) return c ^ 0x20; return c; } char *url_decode(const char *str) { size_t i, j, len = strlen(str); char c, d, url_hex; char *decoded = malloc(len + 1); if (decoded == NULL) return NULL; i = 0; j = 0; do { c = str[i]; d = 0; if (c == '%') { url_hex = to_upper(str[++i]); if (((url_hex >= '0') && (url_hex <= '9')) || ((url_hex >= 'A') && (url_hex <= 'F'))) { d = ascii_hex_4bit[url_hex - 48] << 4; url_hex = to_upper(str[++i]); if (((url_hex >= '0') && (url_hex <= '9')) || ((url_hex >= 'A') && (url_hex <= 'F'))) { d |= ascii_hex_4bit[url_hex - 48]; } else { d = 0; } } } else if (c == '+') { d = ' '; } else if ((c == '*') || (c == '-') || (c == '.') || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')) || (c == '_') || ((c >= 'a') && (c <= 'z'))) { d = c; } decoded[j++] = d; ++i; } while ((i < len) && (d != 0)); decoded[j] = 0; return decoded; }
/** * Locale-independent conversion of ASCII characters to lowercase. */ int av_tolower(int c) { if (c >= 'A' && c <= 'Z') c ^= 0x20; return c; } /** * Decodes an URL from its percent-encoded form back into normal * representation. This function returns the decoded URL in a string. * The URL to be decoded does not necessarily have to be encoded but * in that case the original string is duplicated. * * #param url a string to be decoded. * #return new string with the URL decoded or NULL if decoding failed. * Note that the returned string should be explicitly freed when not * used anymore. */ char *urldecode(const char *url) { int s = 0, d = 0, url_len = 0; char c; char *dest = NULL; if (!url) return NULL; url_len = strlen(url) + 1; dest = av_malloc(url_len); if (!dest) return NULL; while (s < url_len) { c = url[s++]; if (c == '%' && s + 2 < url_len) { char c2 = url[s++]; char c3 = url[s++]; if (isxdigit(c2) && isxdigit(c3)) { c2 = av_tolower(c2); c3 = av_tolower(c3); if (c2 <= '9') c2 = c2 - '0'; else c2 = c2 - 'a' + 10; if (c3 <= '9') c3 = c3 - '0'; else c3 = c3 - 'a' + 10; dest[d++] = 16 * c2 + c3; } else { /* %zz or something other invalid */ dest[d++] = c; dest[d++] = c2; dest[d++] = c3; } } else if (c == '+') { dest[d++] = ' '; } else { dest[d++] = c; } } return dest; } by www.elesos.com