Created
November 15, 2012 06:04
-
-
Save sunxu/4076900 to your computer and use it in GitHub Desktop.
@陈利人 从一个长字符串中查找包含给定字符集合的最短子串。例如,长串为“aaaaaaaaaacbebbbbbdddddddcccccc”,字符集为{abcd},那么最短子串是“acbebbbbbd”。如果将条件改为“包含且只包含给定字符集合”,你的算法和实现又将如何改动。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// minsubstr.c | |
// Test | |
// | |
// Created by 孙 旭 on 12-11-15. | |
// Copyright (c) 2012年 孙 旭. All rights reserved. | |
// | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define true 1 | |
#define false 0 | |
#define error -1 | |
static void add_char_to_hash(int* hash, int hash_size, char chr){ | |
for(int i = 0; i < hash_size; i++){ | |
if(chr == hash[2*i]){ | |
hash[2*i+1]++; | |
return; | |
} | |
} | |
} | |
static void remove_char_from_hash(int* hash, int hash_size, char chr){ | |
for(int i = 0; i < hash_size; i++){ | |
if(chr == hash[2*i]){ | |
hash[2*i+1]--; | |
return; | |
} | |
} | |
} | |
static int check_hash_full(int* hash, int hash_size){ | |
for(int i = 0; i < hash_size; i++){ | |
if(hash[2*i+1] < 1) | |
return false; | |
} | |
return true; | |
} | |
int min_sub_str(const char* str, const char* set, int* start, int* end){ | |
*start = -1; | |
*end = -1; | |
if(NULL == str || NULL == set) | |
return false; | |
int str_len = strlen(str); | |
int set_size = strlen(set); | |
*end = str_len; | |
int* hash= (int*)malloc(sizeof(int) * 2 * set_size); | |
if(NULL == hash) | |
return error; | |
for (int i = 0; i < set_size; i++) { | |
hash[2*i] = set[i]; | |
hash[2*i+1] = 0; | |
} | |
int t_start = 0; //tmp start | |
int t_end = -1; //tmp end | |
while (str[t_start] == str[t_start+1]) { | |
t_start++; | |
} | |
add_char_to_hash(hash, set_size, str[t_start]); | |
int index = t_start+1; | |
while (t_start < str_len || index < str_len) { | |
add_char_to_hash(hash, set_size, str[index]); | |
int is_full = check_hash_full(hash, set_size); | |
if (is_full) { | |
t_end = index; | |
do{ | |
remove_char_from_hash(hash, set_size, str[t_start]); | |
t_start++; | |
}while (check_hash_full(hash, set_size)); | |
if(t_end - t_start + 1 < *end - *start){ | |
*start = t_start - 1; | |
*end = t_end; | |
} | |
} | |
index++; | |
} | |
if (-1 == *start) { | |
return false; | |
} | |
return true; | |
} | |
int main(){ | |
char str[] = "aaaaaaaaaaacbebbbbbdddddddcccccc"; | |
char set[] = "abcd"; | |
int start, end; | |
if(min_sub_str(str, set, &start, &end)){ | |
printf("from %d to %d \n", start, end); | |
for (int i = start; i <= end; i++) { | |
printf("%c", str[i]); | |
} | |
}else{ | |
printf("not found \n"); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
如果将条件改为“包含且只包含给定字符集合”,你的算法和实现又将如何改动。
此时,在73行的while中检测hash是否有值大于等于2。
如果有,则
remove_char_from_hash(. . str[t_start]);t_start++;