Common Operations on Arrays, Linked Lists, and Strings in C++
Array-Based Linear List Manipulations
The following implementation uses a fixed-size array to simulate a dynamic linear list. All mutations reflect directly on a global counter size.
Core Operation Implementations
#include <iostream>
const int CAPACITY = 10000;
int buffer[CAPACITY];
int size = 0;
void addAt(int pos, int value) {
std::cin >> pos >> value;
for (int k = size; k > pos; --k)
buffer[k] = buffer[k - 1];
buffer[pos] = value;
++size;
}
void removeAt(int pos) {
for (int k = pos; k < size - 1; ++k)
buffer[k] = buffer[k + 1];
--size;
}
int locate(int target) {
std::cin >> target;
for (int k = 0; k < size; ++k)
if (buffer[k] == target) return k;
return -1;
}
void countInRange(int lo, int hi) {
int tally = 0;
for (int k = 0; k < size; ++k)
if (buffer[k] >= lo && buffer[k] <= hi) ++tally;
std::cout << tally;
}
void removeDuplicates() {
for (int i = 0; i < size; ++i) {
for (int j = i + 1; j < size; ++j) {
if (buffer[i] == buffer[j]) {
removeAt(j);
--j;
}
}
}
}
void removeRange(int lo, int hi) {
std::cin >> lo >> hi;
int k = 0;
while (k < size) {
if (buffer[k] >= lo && buffer[k] <= hi)
removeAt(k);
else
++k;
}
}
Driver Program
int main() {
int ops, cmd, pos = 0, val = 0, lo = 0, hi = 0;
std::cin >> ops;
while (ops--) {
std::cin >> cmd;
switch (cmd) {
case 1: addAt(pos, val); break;
case 2: std::cin >> pos; removeAt(pos); break;
case 3: std::cout << locate(val) << '\n'; break;
case 4: std::cin >> lo >> hi; countInRange(lo, hi); break;
case 5: removeDuplicates(); break;
case 6: removeRange(lo, hi); break;
}
}
return 0;
}
Key insight: when removeAt is invoked repeatedly inside a loop (e.g., removeDuplicates or removeRange), the loop index must be adjusetd after each deletion to avoid skipping elements. Input reading should also be separated from algorithmic logic to prevent side effects during nested calls.
Merging Two Sorted Sequences
Two ordered arrays can be merged into a single sorted output without building an intermediate result container. The technique uses two pointers that advance through each array, selecting the smaller element at every step.
#include <cstdio>
const int LIMIT = 1000001;
int seqA[LIMIT], seqB[LIMIT];
int main() {
int lenA, lenB;
scanf("%d%d", &lenA, &lenB);
for (int i = 0; i < lenA; ++i) scanf("%d", &seqA[i]);
for (int i = 0; i < lenB; ++i) scanf("%d", &seqB[i]);
int p = 0, q = 0;
while (p < lenA || q < lenB) {
if (q == lenB || (p < lenA && seqA[p] < seqB[q]))
printf("%d ", seqA[p++]);
else
printf("%d ", seqB[q++]);
}
return 0;
}
The conditional (q == lenB || (p < lenA && seqA[p] < seqB[q])) ensures that array boundary are respected and the smaller value is always emitted first.
Linked List Intersection
This operation extracts elements common to both sorted linked lists. The traversal compares current nodes and advances the pointer of the list with the smaller value; on equality, a new node is appended to the result.
#include <cstdio>
#include <cstdlib>
struct LinkNode {
int data;
LinkNode* next;
};
LinkNode* buildList(int count) {
LinkNode *head, *tail, *node;
head = tail = (LinkNode*)malloc(sizeof(LinkNode));
tail->next = nullptr;
for (int i = 0; i < count; ++i) {
int num;
scanf("%d", &num);
node = (LinkNode*)malloc(sizeof(LinkNode));
node->data = num;
node->next = nullptr;
tail->next = node;
tail = node;
}
return head;
}
void printList(LinkNode* lst) {
for (LinkNode* cur = lst->next; cur; cur = cur->next)
printf("%d ", cur->data);
}
LinkNode* intersectLists(LinkNode* A, LinkNode* B) {
LinkNode *head, *tail, *node;
head = tail = (LinkNode*)malloc(sizeof(LinkNode));
tail->next = nullptr;
LinkNode* pa = A->next;
LinkNode* pb = B->next;
while (pa && pb) {
if (pa->data < pb->data)
pa = pa->next;
else if (pb->data < pa->data)
pb = pb->next;
else {
node = (LinkNode*)malloc(sizeof(LinkNode));
node->data = pa->data;
node->next = nullptr;
tail->next = node;
tail = node;
pa = pa->next;
pb = pb->next;
}
}
return head;
}
int main() {
int m, n;
scanf("%d%d", &m, &n);
LinkNode* lstA = buildList(m);
LinkNode* lstB = buildList(n);
LinkNode* result = intersectLists(lstA, lstB);
printList(result);
return 0;
}
String Handling Without Standard Libraries
Concatenation via Pointer Arithmetic
By moving a pointer to the null terminator of the first string, a second string can be appended directly into the same buffer.
#include <cstdio>
char buffer[1 << 20];
int main() {
scanf("%s", buffer);
char* cursor = buffer;
while (*cursor) ++cursor;
scanf("%s", cursor);
printf("%s", buffer);
return 0;
}
Extracting Substrings
Given a starting index and a length, characters are output sequentially after validating bounds.
#include <cstdio>
int main() {
char source[128];
scanf("%s", source);
int start, count;
scanf("%d%d", &start, &count);
int len = 0;
while (source[len]) ++len;
if (start >= 0 && start + count <= len) {
for (int i = start; i < start + count; ++i)
putchar(source[i]);
putchar('\n');
}
return 0;
}
Palindrome Verification
Two indices move inward from the extremes. If any mismatch occurs, the string is not a palindrome.
#include <cstdio>
bool isPalindrome(const char* str) {
int len = 0;
while (str[len]) ++len;
int left = 0, right = len - 1;
while (left < right) {
if (str[left] != str[right]) return false;
++left;
--right;
}
return true;
}
int main() {
char input[256];
scanf("%s", input);
if (isPalindrome(input))
printf("Palindrome\n");
else
printf("Not a palindrome\n");
return 0;
}