-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
/
array_left_rotation.cpp
174 lines (166 loc) · 5.17 KB
/
array_left_rotation.cpp
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/**
* @file
* @brief Implementation for the [Array Left
* Rotation](https://www.javatpoint.com/program-to-left-rotate-the-elements-of-an-array)
* algorithm.
* @details Shifting an array to the left involves moving each element of the
* array so that it occupies a position of a certain shift value before its
* current one. This implementation uses a result vector and does not mutate the
* input.
* @author [Alvin](https://github.com/polarvoid)
*/
#include <cassert> /// for assert
#include <iostream> /// for IO operations
#include <vector> /// for std::vector
/**
* @namespace operations_on_datastructures
* @brief Operations on Data Structures
*/
namespace operations_on_datastructures {
/**
* @brief Prints the values of a vector sequentially, ending with a newline
* character.
* @param array Reference to the array to be printed
* @returns void
*/
void print(const std::vector<int32_t> &array) {
for (int32_t i : array) {
std::cout << i << " "; /// Print each value in the array
}
std::cout << "\n"; /// Print newline
}
/**
* @brief Shifts the given vector to the left by the shift amount and returns a
* new vector with the result. The original vector is not mutated.
* @details Shifts the values of the vector, by creating a new vector and adding
* values from the shift index to the end, then appending the rest of the
* elements from the start of the vector.
* @param array A reference to the input std::vector
* @param shift The amount to be shifted to the left
* @returns A std::vector with the shifted values
*/
std::vector<int32_t> shift_left(const std::vector<int32_t> &array,
size_t shift) {
if (array.size() <= shift) {
return {}; ///< We got an invalid shift, return empty array
}
std::vector<int32_t> res(array.size()); ///< Result array
for (size_t i = shift; i < array.size(); i++) {
res[i - shift] = array[i]; ///< Add values after the shift index
}
for (size_t i = 0; i < shift; i++) {
res[array.size() - shift + i] =
array[i]; ///< Add the values from the start
}
return res;
}
} // namespace operations_on_datastructures
/**
* @namespace tests
* @brief Testcases to check Union of Two Arrays.
*/
namespace tests {
using operations_on_datastructures::print;
using operations_on_datastructures::shift_left;
/**
* @brief A Test to check an simple case
* @returns void
*/
void test1() {
std::cout << "TEST CASE 1\n";
std::cout << "Initialized arr = {1, 2, 3, 4, 5}\n";
std::cout << "Expected result: {3, 4, 5, 1, 2}\n";
std::vector<int32_t> arr = {1, 2, 3, 4, 5};
std::vector<int32_t> res = shift_left(arr, 2);
std::vector<int32_t> expected = {3, 4, 5, 1, 2};
assert(res == expected);
print(res); ///< Should print 3 4 5 1 2
std::cout << "TEST PASSED!\n\n";
}
/**
* @brief A Test to check an empty vector
* @returns void
*/
void test2() {
std::cout << "TEST CASE 2\n";
std::cout << "Initialized arr = {}\n";
std::cout << "Expected result: {}\n";
std::vector<int32_t> arr = {};
std::vector<int32_t> res = shift_left(arr, 2);
std::vector<int32_t> expected = {};
assert(res == expected);
print(res); ///< Should print empty newline
std::cout << "TEST PASSED!\n\n";
}
/**
* @brief A Test to check an invalid shift value
* @returns void
*/
void test3() {
std::cout << "TEST CASE 3\n";
std::cout << "Initialized arr = {1, 2, 3, 4, 5}\n";
std::cout << "Expected result: {}\n";
std::vector<int32_t> arr = {1, 2, 3, 4, 5};
std::vector<int32_t> res = shift_left(arr, 7); ///< 7 > 5
std::vector<int32_t> expected = {};
assert(res == expected);
print(res); ///< Should print empty newline
std::cout << "TEST PASSED!\n\n";
}
/**
* @brief A Test to check a very large input
* @returns void
*/
void test4() {
std::cout << "TEST CASE 4\n";
std::cout << "Initialized arr = {2, 4, ..., 420}\n";
std::cout << "Expected result: {4, 6, ..., 420, 2}\n";
std::vector<int32_t> arr;
for (int i = 1; i <= 210; i++) {
arr.push_back(i * 2);
}
print(arr);
std::vector<int32_t> res = shift_left(arr, 1);
std::vector<int32_t> expected;
for (int i = 1; i < 210; i++) {
expected.push_back(arr[i]);
}
expected.push_back(2);
assert(res == expected);
print(res); ///< Should print {4, 6, ..., 420, 2}
std::cout << "TEST PASSED!\n\n";
}
/**
* @brief A Test to check a shift of zero
* @returns void
*/
void test5() {
std::cout << "TEST CASE 5\n";
std::cout << "Initialized arr = {1, 2, 3, 4, 5}\n";
std::cout << "Expected result: {1, 2, 3, 4, 5}\n";
std::vector<int32_t> arr = {1, 2, 3, 4, 5};
std::vector<int32_t> res = shift_left(arr, 0);
assert(res == arr);
print(res); ///< Should print 1 2 3 4 5
std::cout << "TEST PASSED!\n\n";
}
} // namespace tests
/**
* @brief Function to test the correctness of shift_left() function
* @returns void
*/
static void test() {
tests::test1();
tests::test2();
tests::test3();
tests::test4();
tests::test5();
}
/**
* @brief main function
* @returns 0 on exit
*/
int main() {
test(); // run self-test implementations
return 0;
}