diff options
Fully completed up hw2
1 files changed, 182 insertions, 150 deletions
| -rw-r--r-- | Year 1/Programming introduction/Homeworks/homework2.cpp | 332 |
diff --git a/Year 1/Programming introduction/Homeworks/homework2.cpp b/Year 1/Programming introduction/Homeworks/homework2.cpp index fa0464c..6172c89 100644 --- a/Year 1/Programming introduction/Homeworks/homework2.cpp +++ b/Year 1/Programming introduction/Homeworks/homework2.cpp @@ -1,6 +1,13 @@ #include <iostream> #include <cstring> +void ex0(), ex1(), ex2(); + +int main() +{ + ex0(); +} + /* * Exercise 0 */ @@ -10,79 +17,87 @@ const int MAX_DICT_SIZE = 128, MAX_SRC_SIZE = 1024, MAX_RES_SIZE = 2048; -bool mustAddSpaceBefore(char ch) { +bool mustAddSpaceBefore(char ch) +{ return ch == '-' || ch == '+' || ch == '*' || ch == '/' || ch == '^' || ch == '=' || ch == '('; } -bool mustAddSpaceAfter(char ch) { +bool mustAddSpaceAfter(char ch) +{ return ch == '.' || ch == ',' || ch == '?' || ch == '!' || ch == ';' || ch == ':' || (mustAddSpaceBefore(ch) && ch != '('); } -bool dictItemInStr(int srcSize, char src[MAX_SRC_SIZE], char dictItem[MAX_DICT_ITEM_SIZE], int startInd) { - for (int i = 0; i + startInd < srcSize && dictItem[i] != '-'; i++) { +bool dictItemInStr(int srcSize, const char src[MAX_SRC_SIZE], const char dictItem[MAX_DICT_ITEM_SIZE], int startInd) +{ + for (int i = 0; i + startInd < srcSize && dictItem[i] != '-'; i++) + { if (src[i + startInd] != dictItem[i]) return false; } return true; } -void autoCorrect(int srcSize, char src[MAX_SRC_SIZE], int dictSize, char dict[MAX_DICT_SIZE][MAX_DICT_ITEM_SIZE], char res[MAX_RES_SIZE]) { - char firstLetDict[MAX_DICT_SIZE]; - for (int i = 0; i < dictSize; i++) - firstLetDict[i] = dict[i][0]; - - bool metStartBracket = false; - for (int i = 0, j = 0; i < srcSize && j < MAX_RES_SIZE - 1; i++, j++) { - /* Space before character */ +// Skip over wrong word and put in correct word +void correctWord(char res[MAX_RES_SIZE], int *j, int *i, int *di, const char dict[MAX_DICT_SIZE][MAX_DICT_ITEM_SIZE]) +{ + bool writeInRes = false; - if ((i - 1 > 0 && mustAddSpaceBefore(src[i]) && src[i - 1] != ' ') || - (src[i] == '"' && !metStartBracket)) - res[j++] = ' '; + for (int d = 0; d < MAX_DICT_ITEM_SIZE && dict[*di][d] != '\0'; d++) + { + if (dict[*di][d] == '-') + writeInRes = true; + else if (!writeInRes) + (*i)++; + else + res[(*j)++] = dict[*di][d]; + } +} +void autoCorrect(int srcSize, const char src[MAX_SRC_SIZE], int dictSize, const char dict[MAX_DICT_SIZE][MAX_DICT_ITEM_SIZE], char res[MAX_RES_SIZE]) +{ + bool metStartBracket = false; + for (int i = 0, j = 0; i < srcSize && j < MAX_RES_SIZE - 1; i++, j++) + { /* Dictionary replace */ - bool dictCorrect = false; - - for (int di = 0; di < dictSize; di++) { - if (src[i] != firstLetDict[di]) - continue; - - if (dictItemInStr(srcSize, src, dict[di], i)) { - bool writeInRes = false; - - for (int d = 0; d < MAX_DICT_ITEM_SIZE && dict[di][d] != '\0'; d++) { - if (dict[di][d] == '-') - writeInRes = true; - else if (!writeInRes) - i++; - else - res[j++] = dict[di][d]; - } - i--; j--; + for (int di = 0; di < dictSize; di++) + { + if (dictItemInStr(srcSize, src, dict[di], i)) + { + correctWord(res, &j, &i, &di, dict); break; } } + /* Space before character */ + + if ((i - 1 > 0 && mustAddSpaceBefore(src[i]) && src[i - 1] != ' ') || // Char needs space before it + (src[i] == '"' && !metStartBracket)) // Or is start quote mark + res[j++] = ' '; + /* Normal assign */ - if (!dictCorrect) - res[j] = src[i]; + res[j] = src[i]; /* Dot at end of sentence */ - if (src[i] != '.' && (i + 1 == srcSize || (i + 1 < srcSize && src[i + 1] == '\n'))) { - if (src[i] == '"') { + if (src[i] != '.' && (i + 1 == srcSize || (i + 1 < srcSize && src[i + 1] == '\n'))) // We are at end of sentence + { + if (src[i] == '"' && src[i - 1] != '.') + { res[j] = '.'; res[++j] = '"'; } - else res[++j] = '.'; + else if (src[i] != '"') + res[++j] = '.'; } /* Space after character */ - if ((i + 1 < srcSize && mustAddSpaceAfter(src[i]) && src[i + 1] != ' ') || - (src[i] == '"' && metStartBracket)) + if ((i + 1 < srcSize && mustAddSpaceAfter(src[i]) && src[i + 1] != ' ' && // Char needs space after it + ((src[i] != '.') && (src[i + 1] != '"'))) || // And we don't have ." situation + (src[i] == '"' && metStartBracket)) // Or is end quote mark res[++j] = ' '; /* Next iter init */ @@ -94,14 +109,16 @@ void autoCorrect(int srcSize, char src[MAX_SRC_SIZE], int dictSize, char dict[MA } } -void ex0() { - char str[] = "Lok:1+1=2.\n(\"test\"text", - dict[MAX_DICT_SIZE][MAX_DICT_ITEM_SIZE] = { - "Lok-Look", "tooo-to" +void ex0() +{ + char str[] = "Math 101:1+1=2,2-3=-1,5*5=25,9/3=3,2^3=8,2(3+4)=14\nDont you ever jyst .,;:!?.\nA wise man once said:\"djundjalunga\"\nAnd an een wiser man said \"bruh.\"\n", + dict[MAX_DICT_SIZE][MAX_DICT_ITEM_SIZE] = + { + "Dont-Don't", "jyst-just", "djundjalunga-Oops", "een-even", "bruh-No", "said -said:", "wizer-wiser" }, res[MAX_RES_SIZE]; - autoCorrect(strlen(str), str, 1, dict, res); + autoCorrect(strlen(str), str, 7, dict, res); std::cout << res << std::endl; } @@ -110,44 +127,53 @@ void ex0() { * Exercise 1 */ -void simulateKeyInput1(int **M, int sizeN, int sizeM) { - int values[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; +void simulateKeyInput1(int **M, int sizeN, int sizeM) +{ + int values[] = { 1, 2, 3, 4, 5, 6, 7, 8, 4, 2, 11, 12, 13, 14, 15, 16 }; // A matrix - for (int i = 0; i < sizeN; i++) { + for (int i = 0; i < sizeN; i++) + { for (int j = 0; j < sizeM; j++) M[i][j] = values[i * sizeM + j]; } } -void simulateKeyInput2(int **M, int sizeN, int sizeM) { - int values[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +void simulateKeyInput2(int **M, int sizeN, int sizeM) +{ + int values[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // B matrix - for (int i = 0; i < sizeN; i++) { + for (int i = 0; i < sizeN; i++) + { for (int j = 0; j < sizeM; j++) M[i][j] = values[i * sizeM + j]; } } -void newMatrix(int ***M, int sizeN, int sizeM) { +void newMatrix(int ***M, int sizeN, int sizeM) +{ *M = new int*[sizeN]; for (int i = 0; i < sizeN; i++) (*M)[i] = new int[sizeM]; } -void deleteMatrix(int **M, int sizeN) { +void deleteMatrix(int **M, int sizeN) +{ for (int i = 0; i < sizeN; i++) delete[] M[i]; delete[] M; } -void transformMatrix(int ***A, int N1, int M1, int **B, int N2, int M2) { - if (N1 > N2 || M1 > M2) { +void transformMatrix(int ***A, int N1, int M1, int **B, int N2, int M2) +{ + if (N1 > N2 || M1 > M2) + { int **temp, Nt = (N1 > N2) ? N2 : N1, Mt = (M1 > M2) ? M2 : M1; newMatrix(&temp, Nt, Mt); - for (int i = 0; i < Nt; i++) { + for (int i = 0; i < Nt; i++) + { for (int j = 0; j < Mt; j++) temp[i][j] = (*A)[i][j]; } @@ -156,8 +182,10 @@ void transformMatrix(int ***A, int N1, int M1, int **B, int N2, int M2) { N1 = Nt; M1 = Mt; } - for (int i = 0; i < N1; i++) { - for (int j = 0; j < M1; j++) { + for (int i = 0; i < N1; i++) + { + for (int j = 0; j < M1; j++) + { if ((*A)[i][j] < B[i][j]) (*A)[i][j] = B[i][j]; else if ((*A)[i][j] > B[i][j]) @@ -166,7 +194,8 @@ void transformMatrix(int ***A, int N1, int M1, int **B, int N2, int M2) { } } -void ex1() { +void ex1() +{ int N1 = 4, M1 = 4, N2 = 3, M2 = 3; int **A, **B; @@ -181,7 +210,8 @@ void ex1() { if (N1 > N2) N1 = N2; if (M1 > M2) M1 = M2; - for (int i = 0; i < N1; i++) { + for (int i = 0; i < N1; i++) + { for (int j = 0; j < M1; j++) std::cout << A[i][j] << " "; std::cout << std::endl; @@ -197,85 +227,56 @@ void ex1() { const int MAX_STR = 256; -void subStr(char *str, char *dst, int startInd, int endInd) { +// Substring with inclusive start and end indecies +void subStr(const char *str, char *dst, int startInd, int endInd) +{ for (int i = startInd, j = 0; i <= endInd; i++) dst[j++] = str[i]; } -void splitStr(char *src, char *dstLeft, char *dstRight, int skipStart, int skipEnd) { +void splitStr(const char *src, char *dstLeft, char *dstRight, int skipStart, int skipEnd) +{ subStr(src, dstLeft, 0, skipStart - 1); int len = strlen(src); subStr(src, dstRight, skipEnd + 1, len - 1); } -void symSplitStr(char *src, char *dstLeft, char *dstRight, char *dstLeftover, int skipStart, int skipEnd) { +// Like splitStr, but makes sure left and right are the same length (and separates the leftover) +void symSplitStr(const char *src, char *dstLeft, char *dstRight, char *dstLeftover, int skipStart, int skipEnd) +{ int len = strlen(src); - if (len - skipEnd > skipStart) { + if (len - skipEnd > skipStart) + { subStr(src, dstLeft, 0, skipStart - 1); subStr(src, dstRight, skipEnd + 1, skipEnd + skipStart); subStr(src, dstLeftover, skipEnd + skipStart + 1, len - 1); } - else { + else + { subStr(src, dstLeftover, 0, skipStart - 1 - (len - 1 - skipEnd)); subStr(src, dstLeft, skipStart - (len - 1 - skipEnd), skipStart - 1); subStr(src, dstRight, skipEnd + 1, len - 1); } } -bool isWord(char *str); - -int checkForD(char *str) { - int len = strlen(str); - int status = -1; - - for (int i = 0; i < len; i++) { - if (str[i] == 'D') { - if (status == -1) status = 0; - - char tmpLeft[MAX_STR] = { '\0' }, tmpRight[MAX_STR] = { '\0' }, tmpLeftover[MAX_STR] = { '\0' }; - - int len = strlen(str); - if (i != len - i - 1 && i > 0 && i < len - 1) - symSplitStr(str, tmpLeft, tmpRight, tmpLeftover, i, i); - else - splitStr(str, tmpLeft, tmpRight, i, i); - - if (strcmp(tmpLeft, tmpRight) == 0) - status |= isWord(tmpLeft) && isWord(tmpLeftover); - } - } - - return status; -} - -int checkForC(char *str) { - int len = strlen(str); - - for (int i = 0; i < len; i++) { - if (str[i] == 'C') { - char tmpLeft[MAX_STR] = { '\0' }, tmpRight[MAX_STR] = { '\0' }; - - splitStr(str, tmpLeft, tmpRight, i, i); +bool isWord(const char *str); - return isWord(tmpLeft) && isWord(tmpRight); - } - } - return -1; -} - -int checkForAAB(char *str) { +int checkForAAB(const char *str) +{ int len = strlen(str), indA = -1, indB = -1; - for (int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) + { if ((i < len - 1) && indA < 0 && (str[i] == 'A') && (str[i + 1] == 'A')) indA = ++i; else if (indA >= 0 && str[i] == 'B') indB = i; } - if (indA >= 0 && indB > 0) { - if (indA > 1 || indB < len - 1) - return false; + if (indA >= 0 && indB > 0) + { + if (indA > 1 || indB < len - 1) // When there is stuff around AA<w>B + return false; // Since we check all ways for word parsing, this is fine char tmpMiddle[MAX_STR] = { '\0' }; @@ -283,58 +284,92 @@ int checkForAAB(char *str) { return isWord(tmpMiddle); } - return -1; + return -1; // -1 means we haven't encountered an AAB } -bool isWord(char *str) { +int checkForC(const char *str) +{ int len = strlen(str); - if (len == 0) - return true; - else if (len > 64) - return false; + int status = -1; // -1 means we haven't encountered a C - int tmp; + for (int i = 0; i < len; i++) + { + if (str[i] == 'C') + { + if (status == -1) status = 0; - tmp = checkForD(str); - if (tmp < 0) { - tmp = checkForC(str); - if (tmp < 0) { - tmp = checkForAAB(str); - } - } - if (tmp > 0) return tmp; + char tmpLeft[MAX_STR] = { '\0' }, tmpRight[MAX_STR] = { '\0' }; + + splitStr(str, tmpLeft, tmpRight, i, i); - tmp = checkForC(str); - if (tmp < 0) { - tmp = checkForD(str); - if (tmp < 0) { - tmp = checkForAAB(str); + status |= isWord(tmpLeft) && isWord(tmpRight); } } - if (tmp > 0) return tmp; + return status; +} + +int checkForD(const char *str) +{ + int len = strlen(str); + int status = -1; // -1 means we haven't encountered a D + + for (int i = 0; i < len; i++) + { + if (str[i] == 'D') + { + if (status == -1) status = 0; + + char tmpLeft[MAX_STR] = { '\0' }, tmpRight[MAX_STR] = { '\0' }, tmpLeftover[MAX_STR] = { '\0' }; + int len = strlen(str); - tmp = checkForAAB(str); - if (tmp < 0) { - tmp = checkForD(str); - if (tmp < 0) { - tmp = checkForC(str); + if (i != len - i - 1 && i > 0 && i < len - 1) // When left and right won't have the same size (with exception to one being empty) + symSplitStr(str, tmpLeft, tmpRight, tmpLeftover, i, i); + else + splitStr(str, tmpLeft, tmpRight, i, i); + + if (strcmp(tmpLeft, tmpRight) == 0) + status |= isWord(tmpLeft) && isWord(tmpLeftover); } } - if (tmp > 0) return tmp; + return status; +} - tmp = checkForAAB(str); - if (tmp < 0) { - tmp = checkForC(str); - if (tmp < 0) { - tmp = checkForD(str); +// Tries to parse the str with the given ordering for checks +// An ordering must be a 3 digit number, consisting of the digits 1, 2, 3 (each one used only once) +// Where 1 is checkForAAB, 2 is checkForC and 3 is checkForD +bool tryParse(const char *str, int ordering) +{ + for (int i = 0; i < 3; i++, ordering /= 10) + { + switch (ordering % 10) + { + case 1: if (checkForAAB(str) > 0) return true; break; + case 2: if (checkForC(str) > 0) return true; break; + case 3: if (checkForD(str) > 0) return true; break; + default: return false; } } - if (tmp > 0) return tmp; - return false; } -void ex2() { +bool isWord(const char *str) +{ + int len = strlen(str); + if (len == 0) + return true; + else if (len > 64) + return false; + + // Word checks can be done in multiple orderings, and there needs to be at least one that says str is a word + + return tryParse(str, 321) || // D, C, AAB + tryParse(str, 231) || // C, D, AAB + tryParse(str, 132) || // AAB, D, C + tryParse(str, 123); // AAB, C, D +} + +void ex2() +{ int n; std::cin >> n; @@ -346,12 +381,9 @@ void ex2() { std::cin.ignore(); char str[MAX_STR]; - for (int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) + { std::cin.getline(str, MAX_STR); std::cout << isWord(str) << std::endl; } } - -int main() { - ex2(); -} |
