Website Summary Files Commits Branches @commit @diff @stats
path: root / Week12 / Exercise04.cpp
blob: b10ff9e637c4ec6b450c94827ea48bafd7fd2a1e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>

// Функциите тук "консумират" входния низ, тоест не просто
// превръщат буквите в някаква друга стойност, ами и инкрементират
// указателя, така че да се пропуснат обработените букви.

bool isDigit(char x) {
	return '0' <= x && x <= '9';
}

bool digitsUntil(const char*& str, char end) {
	bool hasAnyDigits = false;

	while (*str != '\0' && *str != end) {
		if (!isDigit(*str))
			return false;
		str++;
		hasAnyDigits = true;
	}

	return hasAnyDigits && *str == end;
}

bool isInteger(const char* text) {
	if (*text == '+' || *text == '-')
		text++;

	return digitsUntil(text, '\0');
}

bool isFloat(const char* text) {
	if (*text == '+' || *text == '-')
		text++;

	if (!digitsUntil(text, '.'))
		return false;
	text++;
	return digitsUntil(text, '\0');
}

bool isLetter(char x) {
	return ('A' <= x && x <= 'Z') || ('a' <= x && x <= 'z');
}

bool isWord(const char* text) {
	while (*text != '\0') {
		if (!isLetter(*text))
			return false;
		text++;
	}
	return true;
}

// В тази функция донякъде има един проблем:
// не проверяваме ако часа ни е 12-часов, дали часа е между 0 и 12 (вместо между 0 и 24).
// Обаче, по условие не ни е казано да проверяваме за това, затова изпускам проверката.
bool isTime(const char* text) {
	if ((text[0] == 'A' || text[0] == 'P') && text[1] == 'M')
		text += 2;

	if (!isDigit(*text) && '0' <= *text && *text <= '2')
		return false;
	text++;

	if (isDigit(*text))
		text++;

	if (*text != ':')
		return false;
	text++;

	if (!isDigit(*text) && '0' <= *text && *text <= '5')
		return false;
	text++;

	if (!isDigit(*text))
		return false;
	text++;

	if ((text[0] == 'A' || text[0] == 'P') && text[1] == 'M')
		text += 2;

	return *text == '\0';
}

bool isPercentage(char* text, unsigned int size) {
	if (!isDigit(*text))
		return false;

	if (text[size - 1] != '%')
		return false;

	text[size - 1] = '\0';

	return isInteger(text) || isFloat(text);
}

char* getInput(unsigned &allocated, unsigned &size);

int main() {
	unsigned int allocated, size;
	char* text = getInput(allocated, size);

	if (size == 0) {
		std::cout << "other" << std::endl;
	}
	else if (isInteger(text)) {
		std::cout << "integer" << std::endl;
	}
	else if (isFloat(text)) {
		std::cout << "float" << std::endl;
	}
	else if (isWord(text)) {
		std::cout << "word" << std::endl;
	}
	else if (isTime(text)) {
		std::cout << "time" << std::endl;
	}
	else if (isPercentage(text, size)) {
		std::cout << "percentage" << std::endl;
	}
	else {
		std::cout << "other" << std::endl;
	}

	delete[] text;

	return 0;
}

char* getInput(unsigned &allocated, unsigned &size) {
	allocated = 8;
	size = 0;

	char* input = new char[allocated];

	char curr;
	std::cin.get(curr);
	while (curr != '\n') {
		input[size++] = curr;
		std::cin.get(curr);

		// Реоразмеряване
		if (size >= allocated) {
			allocated *= 2;
			char* newSentenceArray = new char[allocated];

			for (unsigned i = 0; i < size; i++)
				newSentenceArray[i] = input[i];

			delete[] input;
			input = newSentenceArray;
		}
	}
	input[size] = '\0';

	return input;
}