I want to produce a random sequence of numbers between a range, for example 100 to 200.
After a while, depending on some events, I want to produce a new sequence between the same range (100 to 200), but this time I want to exclude some numbers. For example I don't want [150,165,170].
And the next time, these excluded numbers may or may not be included in the sequence.
One possible approach could be an array of numbers like this:
int rndm[] {100,101,102,103,...};
and use the index of the array to generate a random number at a time:
random(rndm[0-99]);
But I need to use as few instruction/data structures as possible in order to achieve performance.
I am using C for this code and I use random() or randomSeed(seed) and I want to know what the most efficient approach to handle this issue is, in terms of data structures should be used for the speed and memory.
This solution is efficient in the case that there are not many exclusions during the lifetime, once the exclusion function is quadratic.
There is a struct called RandomArray that holds a pointer to and array with size N. N is the desired size of the sequence. The time and space complexity is linear O(N) for the create function.
When an event happens it shall call the function excludeValue, with a time complexity of O(N) and space complexity of 1.
If it is desired to exclude a bunch of values, the function excludeValues (pay attention to s at the end) shall be called. In this case the complexity is O(N x K) and the space complexity is 1. K is the amount of values that shall be excluded.
#include <stdio.h>
#include <stdlib.h>
struct RandomArray {
int *pData;
size_t dataLen;
int excludedIdx;
};
struct RandomArray *excludeValue(struct RandomArray *pAr, int val) {
size_t i;
for (i = 0; i < pAr->excludedIdx; ++i) {
if (pAr->pData[i] == val) {
pAr->excludedIdx--;
int tmp = pAr->pData[i];
pAr->pData[i] = pAr->pData[pAr->excludedIdx];
pAr->pData[pAr->excludedIdx] = tmp;
// Do test again the position
--i;
}
} return pAr;
}
struct RandomArray *excludeValues(struct RandomArray *pAr, int *pVals, size_t len) {
size_t i;
for (i = 0; i < len; ++i)
excludeValue(pAr, pVals[i]);
}
struct RandomArray *destroyRandomArray(struct RandomArray *pAr) {
if (pAr) {
if (pAr->pData)
free(pAr->pData);
pAr->dataLen = 0;
}
return pAr;
}
struct RandomArray *createRandomArray(
struct RandomArray *pAr,
size_t dataLen,
int lowLimit, int highLimit) {
int i;
int range = (highLimit - lowLimit);
pAr->pData = (int*)malloc(sizeof(int) * dataLen);
pAr->dataLen = dataLen;
srand(time(NULL));
for (i = 0; i < dataLen; ++i) {
pAr->pData[i] = rand() % (range + 1) + lowLimit;
}
// Clear excluded indexs
pAr->excludedIdx = pAr->dataLen; return pAr;
}
void printRandomArray(struct RandomArray *pAr) {
size_t i;
printf("Random Array (len = %d): ", pAr->dataLen);
for (i =0; i < pAr->dataLen; ++i) {
printf(" %d", pAr->pData[i]);
}
printf("\n");
}
void printValidRandomArray(struct RandomArray *pAr) {
size_t i;
printf("Valid Random Array (len = %d): ", pAr->excludedIdx);
for (i =0; i < pAr->excludedIdx; ++i) {
printf(" %d", pAr->pData[i]);
}
printf("\n");
}
void printExcludedRandomArray(struct RandomArray *pAr) {
size_t i;
printf("Excluded Random Array (len = %d): ", pAr->dataLen - pAr->excludedIdx);
for (i = pAr->excludedIdx; i < pAr->dataLen; ++i) {
printf(" %d", pAr->pData[i]);
}
printf("\n");
}
void printAllRandomArray(struct RandomArray *pAr) {
printRandomArray(pAr);
printValidRandomArray(pAr);
printExcludedRandomArray(pAr);
}
int main() {
int lowLimit = 100;
int highLimit = 105;
int arrayLen = 10;
struct RandomArray myAr;
createRandomArray(&myAr, arrayLen, lowLimit, highLimit);
printAllRandomArray(&myAr);
printf("\n");
excludeValue(&myAr, 100);
printAllRandomArray(&myAr);
printf("\n");
excludeValue(&myAr, 101);
printAllRandomArray(&myAr);
printf("\n");
excludeValue(&myAr, 102);
printAllRandomArray(&myAr);
printf("\n");
excludeValue(&myAr, 103);
printAllRandomArray(&myAr);
printf("\n");
excludeValue(&myAr, 104);
printAllRandomArray(&myAr);
printf("\n");
excludeValue(&myAr, 105);
printAllRandomArray(&myAr);
destroyRandomArray(&myAr);
createRandomArray(&myAr, arrayLen, lowLimit, highLimit);
printf("\n\n\n");
printAllRandomArray(&myAr);
printf("\n");
int vals[] = { 102, 105, 104 };
excludeValues(&myAr, vals, sizeof(vals) / sizeof(vals[0]));
printAllRandomArray(&myAr);
destroyRandomArray(&myAr);
}
This was asked here on the Arduino forum but I saw it here too. My answer is in Arduino's flavor of C++ since it was posted there...
Of course, performance varies as the set of excluded numbers grows relative to the set of numbers to be used to create your "new sequence."
void setup() {
Serial.begin(115200);
randomSeed(analogRead(A0));
}
void loop() {
// create an arbitray sized array to be filled with unique values to exclude from desired array
const int arraySize = 5;
int exclusions[arraySize];
for (int i = 0; i < arraySize; i++) {
// fill the array with unique values...
int val;
do {
val = random(100, 200);
} while([&]() {
for (auto j : exclusions) {
if (val == j) {
return true;
}
}
return false;
}());
exclusions[i] = val;
}
Serial.print(F("Exclusion Array: "));
for (int i = 0; i < arraySize; i++) {
Serial.print(exclusions[i]);
if (i < arraySize - 1)
Serial.print(F(", "));
}
Serial.println();
// create a new array of arbitrary length of unique random numbers in >>>the same<<< range as above (but not necessary)
Serial.print(F("Starting...\n"));
uint32_t start = millis();
const int listSize = 32;
int list[listSize];
for (int i = 0; i < listSize; i++) {
// fill the array with unique values that will exclude exclusions[]
int val;
do {
val = random(100, 200);
} while([&]() {
for (auto j : list) {
if (val == j) {
return true;
}
for (auto k : exclusions) {
if (val == k) {
return true;
}
}
}
return false;
}());
list[i] = val;
}
uint32_t end = millis();
Serial.println(end - start);
// OPTIONAL -> lets sort the final arry to make spotting the duplicates easier:
for (int i = 0; i < listSize; i++) {
for (int j = i + 1; j < listSize; j++) {
if (list[j] < list[i]) {
int temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
// output the final array
Serial.print(F("Final Array: "));
for (int i = 0; i < listSize; i++) {
Serial.print(list[i]);
if (i < listSize - 1)
Serial.print(F(", "));
}
Serial.print(F("\n\n\n"));
delay(1000);
}
Related
I'm working with integer sequences with non-repeating elements, for some reasons I am tring to remove duplicates by building a hashset.
int * a = {123, 145, 210, 77};
int * b = {145, 77, 123, 210}; // should be removed
int * c = {123, 37, 16};
int * d = {123, 145, 72, 91};
Is there order insensitive hash functions that return same result for a and b?
I have come out of some solutions, but they performs poorly:
sorting - The sequences are immutable, sorting will invlove extra space and O(NlogN) time.
xor - The element in sequences ranges from 0 to hundreds, many bits of hash value may be wasted.
Is there other methods?
Hashing is not the only thing you should do. Because of information loss, completely different arrays could return the same hash. In order to only remove duplicates, you would need to check for equivalence too. A hashset does that too, but places the elements based on a hash, so you can find them more easily.
Here is an example implementation:
#include <stdlib.h>
#include <stdbool.h>
struct hashset {
int count;
int capacity;
struct hashset_element {
int hash;
int arrlen;
int *arrval;
} *elements;
};
void init_hashset(struct hashset *set) {
set->count = 0;
set->capacity = 0;
set->elements = NULL;
}
int hash(int *arr, int len) {
// you can replace this hash function
// this is a pretty simple one
int out = 0;
for (int i = 0; i < len; i++) {
out += arr[i];
}
return out;
}
void arrequals(int *arr1, int len1, int *arr2, int len2) {
if (len1 != len2)
return false;
arr1srt = sort(arr1, len1);
arr2srt = sort(arr2, len2);
for (int i = 0; i < len1; i++) {
if (arr1srt[i] != arr2srt[i])
free(arr1srt);
free(arr2srt);
return false;
}
free(arr1srt);
free(arr2srt);
return true;
}
bool hashset_contains(struct hashset *set, int *arr, int len) {
int rawhash = hash(arr, len);
int hash = rawhash % set->capacity;
for (int i = hash; i < set->capacity; i++) {
if (set->elements[i]->arrval == NULL)
return false;
if (arrequals(set->elements[i]->arrval,
set->elements[i]->arrlen, arr, len)
return true;
}
for (int i = 0; i < hash; i++) {
if (set->elements[i]->arrval == NULL)
return false;
if (set->elements[i]->hash == rawhash &&
arrequals(set->elements[i]->arrval,
set->elements[i]->arrlen, arr, len)
return true;
}
return false;
}
void hashset_realloc(struct hashset *set) {
struct hashset_element* oldarr = set->elements;
int old_capacity = set->capacity;
set->elements = malloc(sizeof(struct hash_element) * set->capacity + 1024);
set->capacity += 1024;
for (int i = 0; i < set->capacity; i++) {
if (oldarr[i]->arrval != NULL)
hashset_add_element(set, oldarr[i]->arrval, oldarr[i]->arrlen);
}
}
void hashset_add_element(struct hashset *set, int *arr, int len) {
if (!hashset_contains(set, arr, len)) {
if (set->count >= set->capacity / 2) {
realloc_hashset(set);
}
int rawhash = hash_element(arr, len);
int hash = rawhash % set->capacity;
for (int i = hash; i < set->capacity; i++) {
if (set->elements[i]->arrval == NULL) {
set->elements[i]->hash = rawhash;
set->elements[i]->arrval = arr;
set->elements[i]->arrlen = len;
set->count++;
return;
}
}
for (int i = 0; i < hash; i++) {
if (set->elements[i]->arrval == NULL) {
set->elements[i]->hash = rawhash;
set->elements[i]->arrval = arr;
set->elements[i]->arrlen = len;
set->count++;
return;
}
}
}
}
void destroy_hashset(struct hashset *set) {
if (set->elements != NULL)
free(set->elements);
}
int hashset_to_array(struct hashset *set, int **arrout, int *lenout, int maxlen) {
int w = 0;
for (int i = 0; i < capacity; i++) {
if (w >= maxlen)
break;
arrout[w] = set->elements[i]->arrval;
lenout[w] = set->elements[i]->arrlen;
w++;
}
return set->count;
}
I did not test this code, but give it a try and feel free to correct me, if there is an error in my code. You have to implement your sort function yourself. I don't know how big the arrays are, you are working with, so I can't pick an ideal algorithm for you. Order insensitive comparing is only possible in O(n*log(n)). O(n) is possible, if the integers have a maximum size, small enough to use a counting table.
In ideal cases this hashset has a runtime of O(1). The worst case runtime is O(n), which is very unlikely to happen. The hash algorithm has a runtime of O(n), which is not ideal but okay for small arrays.
#include <stdio.h>
#include <stdlib.h>
struct arrayADT {
int *A;
int size;
int length;
int *B;
int arr3;
};
struct arrayADT * MergeArray(struct arrayADT *arr1, struct arrayADT *arr2) { //we create thus in heap cuz we need to be able to use these in main function
struct arrayADT *arr3 = (struct arrayADT *)malloc((sizeof(struct arrayADT)));
int i, j, k;
i = j = k = 0;
while(i < arr1->length && j < arr1->length ) {
if(arr1->A[i] < arr2->A[j]) {
arr3->A[k] = arr1->A[i];
k++;
i++;
}
else {
arr3->A[k] = arr2->A[j];
k++;
j++;
}
}
for(; i<arr1->length ; i++) {
arr3->A[k] = arr1->A[i];
k++;
}
for(; j < arr2->length ; j++) {
arr3->A[k] = arr2->A[j];
k++;
}
arr3->length = arr1->length + arr2->length;
arr3->length = 10;
}
void main() {
struct arrayADT arr;
printf("Enter the size of an array");
scanf("%d", &arr.size);
arr.A = (struct arrayADT *)malloc(arr.size * sizeof(int));
arr.length = 0;
int n;
printf("enter the number of elements in an array");
scanf("%d", &n);
printf("enter the elements");
for(int i = 0; i < n; i++) {
scanf("%d", &arr.A[i]);
}
arr.length = n;
display(arr);
printf("Enter second array");
int j;
struct arrayADT *B = (struct arrayADT *)malloc((sizeof(struct arrayADT)));
for(j = 0; j < arr.length; j++) {
scanf("%d", &B[j]);
}
struct arrayADT *arr3 = (struct arrayADT *)malloc(sizeof(struct arrayADT));
arr3 = MergeArray(&arr, &B);
display(*arr3);
I was looking to merge these arrays using heap memory and I am getting segmentation fault. I am new to C programming with pointers and I have been struck here it would be so helpful if I passed this barrier with your help.
And I am not getting where my error lies it would be helpful if someone specifies that too, so that I can avoid these errors in future.
PS: I am using minGW compiler.
In general, your code is rater unorganized. There are several cases for undefined behaviour, for example you don't scan in the second array correctly. The most probably candidate for your segmentaion fault is here:
struct arrayADT *arr3 = (struct arrayADT *)malloc((sizeof(struct arrayADT)));
This will give you an uninitialized chunk of memory. The length and size could of arr3 be anything, and its data field A does not point to valid memory. Accessing it will likely crash.
You have three arrays in your code. You construct each step by step and you treat each differently. That leads to errors easily. Let's go about this more systematically.
Let's create a struct type for a fixed-size array: The maximum size must be given on creation and cannot change. The actual length of the array may be anything from 0 to its maximum size.
typedef struct Array Array;
struct Array {
int *value; // data array
int length; // actual length, 0 <= length <= size
int size; // maximum capacity
};
We create such arrays on the heap and because initializing the members is error-prone, we write a constructor:
Array *array_create(int size)
{
Array *array = calloc(1, sizeof(*array));
array->size = size;
array->value = calloc(size, sizeof(*array->value));
return array;
}
This function creates an empty array for at most size integers. If we allocate memory, we must de-allocate it later, so let's write a corresponding destructor function, which cleans up the ressources:
void array_destroy(Array *array)
{
if (array) {
free(array->value);
free(array);
}
}
After destroying an array, it can no longer be used, just as with memory after calling free() on it.
The array is at first empty, so let's write a function to add elements at its end if there is room:
void array_push(Array *array, int x)
{
if (array->length < array->size) {
array->value[array->length++] = x;
}
}
And a function to print it:
void array_print(const Array *array)
{
printf("[");
for (int i = 0; i < array->length; i++) {
if (i) printf(", ");
printf("%d", array->value[i]);
}
printf("]\n");
}
Now you can create arrays like so:
Array *a = array_create(10);
for (int i = 0; i < a->size; i++) {
array_push(a, i);
}
array_print(a);
array_destroy(a);
Your merge function will be simpler, too. Here's a full example. (But is uses generated array, not arrays typed in by the user.)
#include <stdio.h>
#include <stdlib.h>
typedef struct Array Array;
struct Array {
int *value;
int length;
int size;
};
Array *array_create(int size)
{
Array *array = calloc(1, sizeof(*array));
array->size = size;
array->value = calloc(size, sizeof(*array->value));
return array;
}
void array_destroy(Array *array)
{
if (array) {
free(array->value);
free(array);
}
}
void array_push(Array *array, int x)
{
if (array->length < array->size) {
array->value[array->length++] = x;
}
}
void array_print(const Array *array)
{
printf("[");
for (int i = 0; i < array->length; i++) {
if (i) printf(", ");
printf("%d", array->value[i]);
}
printf("]\n");
}
Array *merge(Array *a, Array *b)
{
Array *res = array_create(a->length + b->length);
int i = 0;
int j = 0;
while(i < a->length && j < b->length) {
if(a->value[i] < b->value[j]) {
array_push(res, a->value[i++]);
} else {
array_push(res, b->value[j++]);
}
}
while(i < a->length) {
array_push(res, a->value[i++]);
}
while(j < b->length) {
array_push(res, b->value[j++]);
}
return res;
}
int main(void)
{
Array *a = array_create(10);
Array *b = array_create(6);
Array *c;
for (int i = 0; i < a->size; i++) {
array_push(a, 1 + 3 * i);
}
for (int i = 0; i < b->size; i++) {
array_push(b, 4 + 2 * i);
}
array_print(a);
array_print(b);
c = merge(a, b);
array_print(c);
array_destroy(a);
array_destroy(b);
array_destroy(c);
return 0;
}
If you've read so far, here's the lowdown:
Organzie your code. That applies to code layout as much as writing small, generally applicable functions instead of doing everything "by hand". (The array type above is a bit on the fence: It uses functions, but getting at the data is still done via accessing the struct fields. You could even change the szie and length, whixh shouldn't really happen.)
Enable compiler warnings with -Wall. You will get useful information about potential (and often actual) errors.
Good luck!
I want to alphabetically sort the struct strings with radix sort, however I am struggling to apply radix sort to check each digit of the strings. I checked other posts but I couldn't find a structure similar to mine.
The problem is that my code checks for each ENTRY of the struct not EACH digit of the string in that entry. (By entry I mean; table[0], table[1] etc.) So basically it sorts the string in itself of each entry. I couldn't build the logic, can someone help me please?
EDIT: the length of the strings are not the same
Here is my code:
typedef struct FUNCTIONS_STRUCT
{
char *fncName;
void (*fnc)(char *);
char *description;
} FUNCTIONS_STRUCT_t;
FUNCTIONS_STRUCT_t FUNC_TABLE[] =
{
{ "ABCD", ABCD, "" },
{ "abcD", abcD, "" },
{ "EaBB", EaBB ,""}
//it goes on ..
};
// Function to find the Largest Number
int getMax(int array[], int n) {
int max = array[0];
int i;
for (i = 1; i < n; i++)
if (array[i] > max)
max = array[i];
return max;
}
// Function for Count sort
void countSort(int array[], int n, int dig) {
int output[n];
int i, count[10] = {0};
for (i = 0; i < n; i++)
count[(array[i] / dig) % 10]++;
for (i = 1; i < 10; i++)
count[i] += count[i - 1];
for (i = n - 1; i >= 0; i--){
output[count[(array[i] / dig) % 10] - 1] = array[i];
count[(array[i] / dig) % 10]--;
}
for (i = 0; i < n; i++)
array[i] = output[i];
}
void radixsort(int array[], int n) {
//Get the largest number to know the maximum number of digits
int m = getMax(array, n);
int dig;
//Counting sort is performed for every digit
for (dig = 1; m / dig > 0; dig *= 10)
countSort(array, n, dig);
}
int main()
{
int functionTableUnitSize = sizeof(FUNC_TABLE) / sizeof(FUNC_TABLE[0]);
radixsort(&FUNC_TABLE, functionTableUnitSize);
return 0;
}
I assume that the function names in your question have a uniform length of 4 alphanumeric characters. In C, identifiers can use 63 different alphanumeric characters from these groups:
lower case (abcdefghijklmnopqrstuvwxyz)
upper case letters (ABCDEFGHIJKLMNOPQRSTUVWXYZ)
digits (0123456789)
and the underscore (_)
Different encodings have a different order (e.g. EBCDIC lower case letters are sorted before upper case letters, while the reverse is true for ASCII). For a portable C programm we can therefore define our own lexical sorting order.
We can do this for example in a function called build_lexical_sorting_index.
Details
I have minimally adjusted the naming from the code you provide in your question
your functions must work with FUNCTION arrays and not with int arrays
radix_sort first creates the lexical sorting index
count_sort must then be called for each of the 4 alphanumeric characters of a function name
words are usually sorted from the leftmost character, that's why we do it this way
count_sort is then called for each of the 4 characters
this determines the index from the lexical_sorting index of the corresponding character from the function name
then the count sorting algorithm as shown in your question is applied
at the end the result is printed
If one slightly modifies your code according to the above mentioned points, it looks like this:
#include <stdio.h>
#define UNIFORM_FUNCNAME_LENGTH 4
typedef struct {
char *fnc_name;
void (*fnc)(char *);
char *description;
} FUNCTION;
void ABCD(char *a) {};
void abcD(char *a) {};
void EaBB(char *a) {};
void A012(char *a) {};
void _ABC(char *a) {};
FUNCTION func_table[] = {
{"ABCD", ABCD, ""},
{"abcD", abcD, ""},
{"EaBB", EaBB, ""},
{"A012", A012, ""},
{"_ABC", _ABC, ""}
//it goes on ..
};
int lexical_sorting_index[256] = {0};
int lexical_index(int ch) {
return lexical_sorting_index[ch];
}
void count_sort(FUNCTION *array, int n, int char_position) {
FUNCTION output[n];
int count[256] = {0};
for (int i = 0; i < n; i++) {
int ch = array[i].fnc_name[char_position];
int index = lexical_index(ch);
count[index]++;
}
for (int i = 1; i < 256; i++)
count[i] += count[i - 1];
for (int i = n - 1; i >= 0; i--) {
int ch = array[i].fnc_name[char_position];
int index = lexical_index(ch);
output[count[index] - 1] = array[i];
count[index]--;
}
for (int i = 0; i < n; i++)
array[i] = output[i];
}
void build_lexical_sorting_index() {
int nr = 0;
for (int i = 'a'; i <= 'z'; i++)
lexical_sorting_index[i] = nr++;
for (int i = 'A'; i <= 'Z'; i++)
lexical_sorting_index[i] = nr++;
for (int i = '0'; i <= '9'; i++)
lexical_sorting_index[i] = nr++;
lexical_sorting_index['_'] = nr;
}
void radix_sort(FUNCTION *array, int n) {
build_lexical_sorting_index();
for(int char_position = UNIFORM_FUNCNAME_LENGTH - 1; char_position >= 0; char_position--)
count_sort(array, n, char_position);
}
int main() {
int table_size = sizeof(func_table) / sizeof(func_table[0]);
radix_sort(func_table, table_size);
for (int i = 0; i < table_size; i++)
printf("%s ", func_table[i].fnc_name);
return 0;
}
When the program is executed, the following is displayed in the debug console:
abcD ABCD A012 EaBB _ABC
I want to delete multiple elements from array using index array,this is my code:
// b is an index array, n is size of b,
// player is the array need to be delete elements,
// size is the size of player
void play_cards(int b[],int n,int player[],int *size){
int i;
for(i = 0; i < n; i++)
delete_cards(b[i],player,size);
}
void delete_cards(int n,int player[],int *size){
int i;
for(i = n; i < *size; i++)
player[i] = player[i+1];
*size -= 1;
}
int main(void){
int player[10] = {1,2,3,3,4,4,5,5,6,7};
int index[6] = {2,3,4,5,6,7};
int size = 10;
play_cards(index,6,player,&size);
for(int i = 0; i < size; i++)
printf("%d|",player[i]);
puts("");
return 0;
}
I expect print the player should be 1,2,6,7 instead of 1,2,3,4. How should I fix it?
First I would not call the function delete_cards as it suggests that it deletes multiple cards which it does not - just delete_card would make things more clear.
Anyway - when you change the player array before you have played all cards in the index array, you change the meaning of the indexes. This is why your current code doesn't work.
So you can do two things:
a) Play all cards first and then delete the cards played. This could be done by first marking played card with -1 and then have a loop where you removed all element being -1
or
b) Play a card, delete it and adjust the remaining elements in index by decrementing them by one. Note: This solution requires that index is sorted (lowest first).
Solution a) could look something like this:
void delete_played_cards(int player[],int *size)
{
int i;
int next_pos = 0;
int deleted = 0;
for(i = 0; i < *size; i++)
{
if (player[i] != -1)
{
player[next_pos] = player[i];
if (i != next_pos)
{
player[i] = -1;
}
++next_pos;
}
else
{
++deleted;
}
}
*size -= deleted;
}
void play_cards(int b[],int n,int player[],int *size)
{
int i;
for(i = 0; i < n; i++)
{
player[b[i]] = -1; // Mark card as played
}
delete_played_cards(player,size);
}
int main(void)
{
int player[10] = {1,2,3,3,4,4,5,5,6,7};
int index[6] = {2,3,4,5,6,7};
int size = 10;
play_cards(index,6,player,&size);
for(int i = 0; i < size; i++)
printf("%d|",player[i]);
puts("");
return 0;
}
Modify play_cards:
void play_cards(int b[], int n, int player[], int *size)
{
int i;
for(i = n-1; i >= 0; i--)
delete_cards(b[i],player,size);
}
This will start deleting from the end of array.
As BLUEPIXY mentioned.
here is a pseudocode that you can work with:
given a sorted list, 1..n
for i = 2 up to length of list:
if list[i] is equal to list[i-1]:
shift the sublist [2..] 1 position to the left
else
increment i by 1
If you want to delete easily and efficiently without using loop you can use memcpy
#include <stdio.h>
#include <string.h>
#define INDEX_MAX 6
int main ()
{
int size = 10;
int src[] = {1,2,3,3,4,4,5,5,6,7};
int index[] = {2,3,4,5,6,7};
int x;
size = size - INDEX_MAX;
memcpy(src+2, src+8, sizeof(int)*(size-2));// - 2 since index 1 and 2 remains in the array
for(x = 0; x < size; x++){
printf("%d",src[x]);
}
return(0);
}
I'm using a for loop to create an 100 element array of char. I on the first run, I want to change all of its values to 1, the second run, I want its every second values to 0
char array[ 100 ] = { 0 };
int toggle_swith(char a[]) {
for (i = 0; i < 100; i++) {
printf(array[i] + "1 ");
}
}
int main( void ) {
int i;
for (i = 0; i < 100; i++) {
printf(array[i] + "0 ");
toggle_switch();
}
}
You need a function which initializes the array:
void InitializeArray(char Array[], int Length) {
int i;
for (i = 0; i < Length; i++) {
Array[i] = '1';
}
}
You need a function which changes every 2nd element:
void ChangeEverySecondElement(char Array[], int Length) {
int i;
for (i = 1; i < Length; i += 2) {
Array[i] = '0';
}
}
You need a function to print the array :
void PrintArray(char Array[], int Length) {
int i;
for (i = 0; i < Length; i++) {
putchar(Array[i]);
putchar(' ');
}
putchar('\n');
}
Then you need to put them together
int main() {
char Array[100];
InitializeArray(Array, 100);
PrintArray(Array, 100);
ChangeEverySecondElement(Array, 100);
PrintArray(Array, 100);
return 0;
}
If you are trying to learn C, I recommend the book I learned it from, C by Example written by Greg Perry.
you can do it all at once
for (i=0; i<100; i++) array[i]=(i%2)+'0';
a typical attempt at optimization could look like:
#define BUFSZ 100
int main(){
char buf[BUFSZ];
int *bp=(int *)&buf, i=(BUFSZ/sizeof(int));
/* handle aligned words 4 bytes at a time */
while (i) bp[--i]='0101'; /* for 64 bit use '0101'|('0101' <<32) */
/* handle unaligned bytes */
for(i=(BUFSZ/sizeof(int))*sizeof(int);i<BUFSZ;i++)buf[i]=1-i%2+'0';
write(1,buf,BUFSZ);
}
Initially you want to make all your array elements as 1
You can use memset
memset(array,1,100)
This will clear all elements. But if you insist on using a loop then,
#define ARRAY_SIZE 100
char array[ARRAY_SIZE] = {0};
for(int count = 0; count < ARRAY_SIZE; count++)
{
array[count] = 1;
//If you want to print it, use:
printf("%d",array[count]; // You can also use %c
}
To make alternate element 0,
for(int count = 0; count < ARRAY_SIZE; (count = count + 2)) //Count + 2 will hop every alternate element
{
array[count] = 0;
}
Again, You can add printf() if you want.
Print statement should look something like this.
printf("%c0",array[i]);
I suggest you look up Beginner C tutorial for more info.