之前有朋友面试笔试被考到了这个问题,挺好的面试题。
既然是iOS面试题,肯定不能像C实现那样,写一大堆hashTable的结构体的代码,可以用Foundation对象哟
NSString *str = @"aabbcdeffffadisldkfidjsdflksjdfie";
NSMutableArray *arr = [NSMutableArray array];
NSUInteger maxOccurence = 0;
unichar tempChr = 0;
[str enumerateSubstringsInRange:NSMakeRange(0, [str length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[arr addObject:substring];
}] ;
NSCountedSet *set = [[NSCountedSet alloc] initWithArray:arr]; /* 这是个好东西,去重并计数的Set */
// 第一种方法
for (int i=0; i<[str length]; ++i) {
unichar chr = [str characterAtIndex:i];
NSUInteger tmp = [set countForObject:[NSString stringWithCharacters:&chr length:1]];
if (maxOccurence < tmp) {
maxOccurence = tmp;
tempChr = chr;
}
}
NSLog(@"%lu, %c", (unsigned long)maxOccurence, tempChr); // 出现最多的数量 和 是哪个字符
// 第二种方法
NSMutableArray *dictArray = [NSMutableArray array];
[set enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) {
[dictArray addObject:@{@"object": obj,
@"count": @([set countForObject:obj])}];
}];
NSLog(@"%@, %@", [[[dictArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"count" ascending:NO]]] objectAtIndex:0] objectForKey:@"object"], [[[dictArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"count" ascending:NO]]] objectAtIndex:0] objectForKey:@"count"]); // 对数组进行DESC排序 取idx = 0的字典,然后取数据
NSCountedSet也可以统计单词出现的次数。例如:
NSString *str = @"You are damn right, you are damn good.";
NSCountedSet *set = [[NSCountedSet alloc] init];
[str enumerateSubstringsInRange:NSMakeRange(0, [str length]) options:NSStringEnumerationByWords | NSStringEnumerationLocalized usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
[set addObject:substring];
}];
NSEnumerator *iterator = [set objectEnumerator];
NSString* temp;
while (temp = [iterator nextObject]) {
NSLog(@"%@, %lu", temp, [set countForObject:temp]);
}
Output:
damn, 2
right, 1
you, 1
good, 1
are, 2
You, 1
很好用的对象,继承NSMutableSet.
用Shell试试,
echo "You are damn right, you are damn good." | tr -s ' ' '\n' | sort | uniq -c | awk '{print $2, $1}' | sort -rn -k2
输出:
damn 2
are 2
you 1
right, 1
good. 1
You 1
跑题了。。脑子里面老是有引申的意思。
如果用C去实现肿么整?上面提到了hashTable,这个是没问题的
typedef struct item {
int data;
int key;
struct item* next;
} Item;
typedef struct hashtable {
int size;
struct item **table;
} Hashtable;
实现以下方法:
void freeHashTable(Hashtable* ht);
Hashtable* createHashTable(int size);
int genHash(Hashtable *hashtable, int key);
void addToHashTable(Hashtable* ht, Item* item);
Item* getItemFromHashTable(Hashtable* ht, int key);
genHash其实是根据key,返回数组的下标,下标的值就是hash。又跑题了。
通过遍历字符串中的字符,写入HashTable, 已经存在的就+1,并且保存当前出现的最大值,一遍之后就取得正确答案。
这个方法要实现一个HashTable,还挺麻烦的。
后来我想,如果不考虑空间复杂度的话,其实字符是有ascii码的,如果不考虑多字节编码的话,那也是有限的哟
#define ASCIISIZE 256
int arr[ASCIISIZE] = {0};
unsigned int maxOccurence = 0;
char ret;
一个for循环,加入数组对应的ascii下标,并且保存当前出现的最大值,一遍之后也出来了,很方便,使用数组就搞定了。
for (int i = 0; i < strlen(str); ++i)
{
arr[str[i]]++;
if (maxOccurence < arr[str[i]])
{
maxOccurence = arr[str[i]];
ret = str[i];
}
}
好吧。一个小算法题引申了不少内容。