Skip to content

Instantly share code, notes, and snippets.

@shergin
Last active August 29, 2015 14:13
Show Gist options
  • Save shergin/5d2b479be0f9761fb380 to your computer and use it in GitHub Desktop.
Save shergin/5d2b479be0f9761fb380 to your computer and use it in GitHub Desktop.
Finding the most frequent character in string
#import <Foundation/Foundation.h>
#import <stdio.h>
#include <math.h>
#include <time.h>
typedef unsigned long characters_count_t;
typedef char character_t;
typedef unsigned char unsigned_character_t;
void mostFrequentCharacterEx(character_t *str, characters_count_t size, character_t *character, characters_count_t *count)
{
characters_count_t characters = pow(2, sizeof(character_t) * 8); // actually `sizeof(char)` is platform depended
characters_count_t *counts = calloc(characters, sizeof(characters_count_t));
for (characters_count_t i = 0; i < size; i++) {
counts[(unsigned_character_t)str[i]] ++;
}
*count = 0;
for (characters_count_t i = 0; i < characters; i++) {
if (*count < counts[i]) {
*count = counts[i];
*character = i;
}
}
free(counts);
}
character_t mostFrequentCharacterOneThread(character_t* string, characters_count_t size)
{
character_t character;
characters_count_t count;
mostFrequentCharacterEx(string, size, &character, &count);
return character;
}
character_t mostFrequentCharacterMultiThreaded(character_t* string, characters_count_t size)
{
int buckets_count = 2;
characters_count_t bucket_size = size / buckets_count;
character_t *bucket_result_character = calloc(buckets_count, sizeof(character_t));
characters_count_t *bucket_result_count = calloc(buckets_count, sizeof(characters_count_t));
dispatch_queue_t queue = dispatch_queue_create("com.yandex.careers.challenge", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < buckets_count; i++) {
character_t *current_bucket_start = string + i * bucket_size;
characters_count_t current_bucket_size = (i + 1 < buckets_count) ? bucket_size : (size - (buckets_count - 1) * bucket_size);
dispatch_async(queue, ^{
int index = i;
mostFrequentCharacterEx(
current_bucket_start,
current_bucket_size,
bucket_result_character + index,
bucket_result_count + index
);
});
}
character_t __block character;
dispatch_barrier_sync(queue, ^{
character = bucket_result_character[0];
characters_count_t characters = pow(2, sizeof(character_t) * 8); // actually `sizeof(char)` is platform depended
characters_count_t *counts = calloc(characters, sizeof(characters_count_t));
for (characters_count_t i = 0; i < buckets_count; i++) {
counts[(unsigned_character_t)bucket_result_character[i]] += bucket_result_count[i];
}
character_t character = '\0';
characters_count_t maximum = 0;
for (characters_count_t i = 0; i < characters; i++) {
if (maximum < counts[i]) {
maximum = counts[i];
character = (character_t)i;
}
}
free(counts);
});
return character;
}
void generateTestCase(character_t *string, characters_count_t length, character_t favoir_character)
{
for (characters_count_t i = 0; i < length; i++) {
if (i % 100 == 42) {
string[i] = favoir_character;
continue;
}
string[i] = (character_t)rand();
}
}
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSLog(@"Generating test case...");
characters_count_t length = 1024 * 1024 * 512;
character_t *string = calloc(length, sizeof(character_t));
character_t character;
generateTestCase(string, length, 'Y');
clock_t start;
clock_t stop;
float seconds;
NSLog(@"Finding the most frequent character in one thread...");
start = clock();
character = mostFrequentCharacterOneThread(string, length);
stop = clock();
seconds = (float)(stop - start) / CLOCKS_PER_SEC;
NSLog(@"The most frequent character is '%c', spent %f seconds.", character, seconds);
NSLog(@"Finding the most frequent character in multiple threads...");
start = clock();
character = mostFrequentCharacterMultiThreaded(string, length);
stop = clock();
seconds = (float)(stop - start) / CLOCKS_PER_SEC;
NSLog(@"The most frequent character is '%c', spent %f seconds.", character, seconds);
NSLog(@"All done.");
free(string);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment