Created
October 23, 2015 17:32
-
-
Save dralletje/89d5bc5eed1d5deb962c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <iostream> | |
#include <fstream> | |
#include <assert.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
using namespace std; | |
const int max_word_length = 60; | |
const int max_words_length = 300000; | |
const int max_command_length = 100; | |
const int max_filename_length = 80; | |
typedef char Word [max_word_length]; | |
typedef Word Words [max_words_length]; | |
// Overwrite the array at one position with the content of an other array | |
void copy_word(Word target, Word source) { | |
for (int i = 0; i < max_word_length; i = i + 1) { | |
target[i] = source[i]; | |
} | |
} | |
// Print a string with a newline | |
void print(string msg) { | |
cout << msg << "\n"; | |
} | |
// Check two word arrays for equality | |
bool compare_word(Word one, Word two) { | |
string one_string(one); | |
string two_string(two); | |
return one_string == two_string; | |
} | |
// Find index of Word in Words. If not found, return negative index. | |
int find_occurence(Word needle, Words haystack, int words_count, int offset) { | |
// Offset cant be off limits | |
assert(offset < words_count); | |
assert(words_count > 0); | |
for(int i = offset; i < words_count; i = i + 1) { | |
if(compare_word(haystack[i], needle)) { | |
return i; | |
} | |
} | |
return -1; | |
} | |
// Make sure there is a sequence like the one in `input` at the position | |
// `words_index` in the array `words` | |
bool ensure_sequence(Words input, int input_length, Words words, int words_count, int words_index, int input_offset) { | |
assert(input_offset <= input_length); | |
assert(words_index <= words_count); | |
int real_length = input_length - input_offset; | |
int input_index = 0; | |
// No sequence given.. guess that's always correct then | |
if (real_length == 0) { | |
return words_index; | |
} | |
// Loop over both arrays to compare them | |
while( | |
words_index + input_index <= words_count && | |
compare_word(input[input_index + input_offset], words[words_index + input_index]) | |
) { | |
input_index = input_index + 1; | |
if(real_length == input_index) { | |
return true; | |
} | |
} | |
return false; | |
} | |
// Just wrap `find_occurence` and `ensure_sequence` | |
int find_sequence( | |
Words input, int input_length, Words words, | |
int words_count, int input_offset, int offset | |
) { | |
assert(offset <= words_count); | |
assert(input_offset <= input_length); | |
int index = find_occurence(input[input_offset], words, words_count, offset); | |
if (index != -1 && ensure_sequence(input, input_length, words, words_count, index, input_offset)) { | |
return index; | |
} else { | |
return -1; | |
} | |
} | |
// Given by the exercise | |
bool read_word (ifstream& infile, Word word) { | |
infile >> word; | |
return word; | |
} | |
// Load words from a file stream and put them in an array | |
int read_words (ifstream& infile, Words words) { | |
assert(infile.is_open()); | |
int word_counter = 0; | |
Word word; | |
while (read_word(infile, word) == true) { | |
if (!infile) { | |
break; | |
} | |
copy_word(words[word_counter], word); | |
word_counter = word_counter + 1; | |
} | |
return word_counter; | |
} | |
Words words_read; | |
Words words_input; | |
Word empty_word; | |
int main() { | |
int words_count; | |
for(int i = 0; i < max_word_length; i = i + 1) { | |
empty_word[i] = '\0'; | |
} | |
while (true) { | |
// Reset the array of command words | |
for (int i = 0; i < max_words_length; i = i + 1) { | |
copy_word(words_input[i], empty_word); | |
} | |
// Request new command | |
cout << "\n> "; | |
char input[max_command_length]; | |
for(int i = 0; i < max_command_length; i = i + 1) { | |
input[i] = '\0'; | |
} | |
cin.getline(input, max_command_length); | |
cin.clear(); | |
// Split it up in words | |
int words_index = 0; | |
int char_index = 0; | |
for (int i = 0; i < max_command_length; i = i + 1) { | |
char current = input[i]; | |
if (current != ' ') { | |
words_input[words_index][char_index] = current; | |
char_index = char_index + 1; | |
} else { | |
words_index = words_index + 1; | |
char_index = 0; | |
} | |
} | |
int input_length = words_index + 1; | |
string command = words_input[0]; | |
if(command == "enter") { | |
ifstream infile; | |
string filename; | |
if (input_length < 2) { | |
print("`enter` requires at least one argument."); | |
continue; | |
} | |
// Construct filename from args | |
for (int i = 1; i < input_length; i = i + 1) { | |
if (i == 1) { | |
filename = words_input[i]; | |
} else { | |
filename = filename + " " + words_input[i]; | |
} | |
} | |
// I find assert here a little too agressive | |
infile.open(filename); | |
if(!infile.is_open()) { | |
print("Opening file failed, have another try."); | |
continue; | |
} | |
// Read it! | |
words_count = read_words(infile, words_read); | |
// Notify the user | |
print("Sucessfully opened file " + filename + "."); | |
print("A total of " + to_string(words_count) + " words counted."); | |
continue; | |
} | |
if (command == "content") { | |
// Print every word | |
for(int i = 0; i < words_count; i = i + 1) { | |
cout << words_read[i] << " "; | |
} | |
print(""); | |
continue; | |
} | |
// Simply exit the programmmmm | |
if (command == "stop") { | |
if (input_length > 1) { | |
print("`stop` doesn't take any arguments."); | |
continue; | |
} | |
print("Bye!"); | |
exit(0); | |
} | |
if (command == "count") { | |
if (input_length < 2) { | |
print("`count` requires at least one argument."); | |
continue; | |
} | |
// Find every sencuence occurence and increase `count` | |
int count = 0; | |
int index = find_sequence(words_input, input_length, words_read, words_count, 1, 0); | |
while(index != -1) { | |
count = count + 1; | |
int position = index + input_length; | |
index = find_sequence(words_input, input_length, words_read, words_count, 1, position); | |
} | |
// Just to print it here | |
print("Found the sequence " + to_string(count) + " times."); | |
continue; | |
} | |
if (command == "where") { | |
if (input_length < 2) { | |
print("`count` requires at least one argument."); | |
continue; | |
} | |
// Go over all found sequences, but also display the index they are found at. | |
int count = 0; | |
int index = find_sequence(words_input, input_length, words_read, words_count, 1, 0); | |
while(index != -1) { | |
print("Found at position " + to_string(index) + "."); | |
count = count + 1; | |
int position = index + input_length; | |
index = find_sequence(words_input, input_length, words_read, words_count, 1, position); | |
} | |
// And the total number ofcourse | |
print("Found the sequence " + to_string(count) + " times."); | |
continue; | |
} | |
if (command == "context") { | |
if (input_length < 3) { | |
print("`content` requires at least two arguments."); | |
continue; | |
} | |
// Convert string argument to number | |
int m = atoi(words_input[1]); | |
// Error if it's not a number or lower than 1 | |
if(m < 1) { | |
print("first argument for `content` should be a *number* higher than 0."); | |
continue; | |
} | |
// Again, find all sequences | |
int count = 0; | |
int index = find_sequence(words_input, input_length, words_read, words_count, 2, 0); | |
while(index != -1) { | |
// But now, also print all words around it | |
cout << "|"; | |
int begin = max(index - m, 0); | |
int end = min(index + input_length + m - 2, words_count); | |
for(int i = begin; i < end; i = i + 1) { | |
cout << " " << words_read[i]; | |
} | |
print(""); | |
// And as usual, count it... | |
count = count + 1; | |
int position = index + input_length; | |
index = find_sequence(words_input, input_length, words_read, words_count, 2, position); | |
} | |
// ... and print it | |
print("Found the sequence " + to_string(count) + " times."); | |
continue; | |
} | |
cout << "please enter a valid choice" << endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment