C 给定间隔内的随机字符串
我想用这个签名创建一个函数C 给定间隔内的随机字符串,c,string,random,C,String,Random,我想用这个签名创建一个函数 char *generateString(char *par1, char *par2); 结果应该是严格大于par1(与strcmp相比)且严格小于par2的字符串。Par1和par2的随机长度介于0和最大值之间 每个字符在[INF,SUP]间隔之间选择。(参数是由这些字符组成的字符串) 字符串长度是有限的,但也是随机的,介于0和某个最大值之间 似乎很难编码,任何人都可以帮助?这个问题要求在独占范围内输入一个随机字符串。下面的解决方案给出了一个包含范围内的随机字符
char *generateString(char *par1, char *par2);
结果应该是严格大于par1
(与strcmp
相比)且严格小于par2
的字符串。Par1和par2的随机长度介于0和最大值之间
每个字符在[INF,SUP]
间隔之间选择。(参数是由这些字符组成的字符串)
字符串长度是有限的,但也是随机的,介于0和某个最大值之间
似乎很难编码,任何人都可以帮助?这个问题要求在独占范围内输入一个随机字符串。下面的解决方案给出了一个包含范围内的随机字符串。结果证明,解决包容性范围问题要容易得多。如果我们想要一个独占范围,我们只需在生成的字符串落在范围的边界上时拒绝它,并生成另一个随机字符串,直到它不在范围的边界上。我为此添加了函数
randstrx()
为了说明我的解决方案,我们考虑十进制数字串,即其字符在范围<代码> C=(0 9)< /代码>。例如,任意长度的
00127
,66501
,23
,1
,等等。考虑给定长度的所有字符串,例如“代码> 4”/代码>。显然,这些字符串上存在一个顺序。例如,对于十进制数字字符串,长度4
的字符串的顺序如下:0000
,0001
,0002
,…,9999
给定给定长度的任何字符串,可以很容易地计算字符串顺序中紧跟其后或之前的相同长度的字符串(我们忽略两种边界情况,其中没有后字符串或前字符串,因为我们不需要它们)。对于十进制数字串,我们只需加或减1
。加法和减法在任何基中都有很好的定义,数字可以由任何符号组成,它们不必是十进制数字。因此,它定义了如何将1
(或一个单位)添加或减去给定长度的任何字符串。我们将在下面使用它
设S1
和S2
分别为字符串范围的包含下限和上限。我们有S1=0
和N2>=0
分别是T1
和T2
的长度。我们考虑4种情况:
和N1=0
在这种情况下,N2=0
,因此范围S1=S2=Sk
包含一个长度[s1s2]
的字符串K
。因此,Sk
是L=K
的唯一可能值L
和N1>0
这种情况是不可能的,因为我们假设N2=0
显然,s10
必须至少是L
S1和K
的公共字符序列的长度。为了确定<代码> L>代码>的上界,我们需要考虑<代码> T2。如果S2
可以递减,这意味着我们可以生成小于T2
的任意长度的字符串。例如,如果S2
和S1=123
,S2=123001
小于12300099…9
(和S2
)。>S1
不能递减的唯一情况是T2
。例如,如果T2=C1+C1+…+C1
和S1=123
,S2=123000
不能递减。无法生成小于T2
且长度大于S2
的字符串。所以在这种情况下,L2
必须在L
范围内[kl2]
T1
,并且T1
和T2
的第一个字符不相等,如果它们相等,那么公共第一个字符将位于公共起始序列Sk
中。这意味着T1
可以递增,或者T2
可以递减。事实上,例如,在十进制数字串中,唯一不能递增的T1
是99…9
。如果T1
等于此值,则这也必须是T2
的值,但是T1
等于T2
,并且T1
和T2
必须在Sk
中,这是一个矛盾。对于T2
,也可以进行类似的推理。唯一不能递减的T2
是T2=00…0
,因此T1
也必须是00…0
,这将把T1
和T2
放在Sk
中,这是一个矛盾。因为T1
可以递增,T2
可以递减,所以我们可以生成随机字符串或大于T1
且小于T2
的任意长度。例如,如果S1=1231
和S2=1234
,则字符串12311…1
和123399…9
属于范围[S1 S2]
。考虑<代码> L>代码>的下限。任何长度K
的字符串都必须等于Sk
,但由于N1>0
,Sk
小于S1
。因此,随机字符串的长度不能为K
。然而,很容易证明它的长度可以是K+1
。我们知道T1
的第一个字符T1[0]
小于T2
的第一个字符,并且它可以增加。因此,附加字符T1[0]+1
的字符串Sk
是长度K+1
的字符串,大于S1
。它也小于或等于S2
。实际上,如果T2[0]=T1[0]+1
和N2=1
,则ra
#include "stdlib.h"
#include "string.h"
#include "assert.h"
#include "time.h"
/* Generate a random string in inclusive range [S1 S2] of maximum length M. */
/* S1, S2, and the returned random string have their characters in the range [C1 C2]. */
/* Returns NULL if no string of maximum length M exists in [S1 S2]. */
char * randstr(char * S1, char * S2, int M, int C1, int C2)
{
/* Validate inputs. */
if (S1 == NULL || S2 == NULL || *S1 == 0 || *S2 == 0) return NULL;
if (strcmp(S1, S2) > 0) return NULL;
if (C1 > C2) return NULL;
/* Lengths of input strings. */
int L1 = strlen(S1);
int L2 = strlen(S2);
/* Length of longest common starting sequence of S1 and S2. */
int K = 0;
for (; K < L1 && K < L2 && S1[K] == S2[K]; K++);
/* Generate length of random string S. */
int L;
int N1 = L1 - K;
int N2 = L2 - K;
if (N1 == 0 && N2 == 0)
{
/* L = K */
if (M < K) return NULL;
L = K;
}
else if (N1 > 0 && N2 > 0)
{
/* L = [K + 1 M] */
if (M < K + 1) return NULL;
L = (rand() % (M - (K + 1) + 1)) + K + 1;
}
else if (N1 == 0 && N2 > 0)
{
char * T2 = S2 + K;
while (*T2 > 0 && *T2 == C1)
T2++;
if (*T2 == 0) /* T2 = C1 + C1 + ... + C1 */
{
/* L = [K L2] */
if (M < K) return NULL;
if (M < L2)
L = (rand() % (M - K + 1)) + K;
else
L = (rand() % (L2 - K + 1)) + K;
}
else
{
/* L >= K */
if (M < K) return NULL;
L = (rand() % (M - K + 1)) + K;
}
}
/* Compute smallest string S1L of length L that is greater than S1. */
char * S1L = (char*)malloc(sizeof(char) * (L + 1));
S1L[L] = 0;
if (L >= L1)
{
for (int i = 0; i < L1; S1L[i] = S1[i++]); /* Copy S1 into S1L. */
for (int i = L1; i < L; S1L[i++] = C1); /* Append C1 characters. */
}
else /* L < L1 */
{
for (int i = 0; i < L; S1L[i] = S1[i++]); /* Set S1L to S1 truncated to length L. */
for (int i = L - 1; i >= 0; i--) /* Increment S1L. */
{
if (S1L[i] < C2)
{
S1L[i]++;
break;
}
else
S1L[i] = C1;
}
}
/* Compute largest string S2L of length L that is less than S2. */
char * S2L = (char*)malloc(sizeof(char) * (L + 1));
S2L[L] = 0;
if (L > L2)
{
for (int i = 0; i < L2; S2L[i] = S2[i++]); /* Copy S2 into S2L. */
for (int i = L2; i < L; S2L[i++] = C2); /* Append C2 characters. */
for (int i = L2 - 1; i >= 0; i--) /* Decrement copy of S2. */
{
if (S2L[i] > C1)
{
S2L[i]--;
break;
}
else
S2L[i] = C2;
}
}
else /* L < L2 */
{
for (int i = 0; i < L; S2L[i] = S2[i++]); /* Set S2L to S2 truncated to length L. */
}
/* Generate random string S of length L in range [S1L S2L]. */
char * S = (char*)malloc(sizeof(char) * (L + 1));
S[L] = 0;
for(int i = 0; i < L; i++)
S[i] = (rand() % (S2L[i] - S1L[i] + 1)) + S1L[i];
free(S1L);
free(S2L);
return S;
}
/* Generate a random string in exclusive range (S1 S2) of maximum length M. */
/* S1, S2, and the returned random string have their characters in the range [C1 C2]. */
/* Returns NULL if no string of maximum length M exists in (S1 S2). */
char * randstrx(char * S1, char * S2, int M, int C1, int C2)
{
/* If S1 + 1 >= S2, then no random string exists in (S1 S2). */
int L1 = strlen(S1);
char * S = (char*)malloc(sizeof(char) * (L1 + 1));
strcpy(S, S1);
for (int i = L1 - 1; i >= 0; i--)
{
if (S[i] < C2)
{
S[i] += 1;
break;
}
}
if (strcmp(S, S2) >= 0)
{
free(S);
return NULL;
}
do
{
free(S);
S = randstr(S1, S2, M, C1, C2);
}
while (strcmp(S, S1) == 0 || strcmp(S, S2) == 0);
return S;
}
int main()
{
srand((unsigned int)time(NULL)); // initialisation de rand
char * s;
/* N1 == 0, N2 == 0, K == 1 */
s = randstr("0", "0", 10, '0', '9');
assert(strcmp(s, "0") == 0);
/* N1 == 0, N2 == 0, K == 4 */
s = randstr("1210", "1210", 10, '0', '9');
assert(strcmp(s, "1210") == 0);
/* N1 == 0, N2 == 1, K == 3, T2 == 0 */
s = randstr("121", "1210", 3, '0', '9');
assert(strcmp(s, "121") == 0);
/* N1 == 0, N2 == 1, K == 3, T2 == 0 */
s = randstr("121", "1210", 4, '0', '9');
assert(strcmp(s, "121") == 0 || strcmp(s, "1210") == 0);
/* N1 == 1, N2 == 1, K == 3, T2 != 0 */
s = randstr("1210", "1211", 4, '0', '9');
assert(strcmp(s, "1210") == 0 || strcmp(s, "1211") == 0);
/* N1 == 1, N2 == 1, K == 3, T2 != 0 */
s = randstr("1210", "1211", 5, '0', '9');
assert(strcmp(s, "1210") >= 0 || strcmp(s, "1211") <= 0);
/* N1 == 4, N2 == 1, K == 0, T2 != 0 */
s = randstr("0004", "1", 25, '0', '9');
assert(strcmp(s, "0004") >= 0 || strcmp(s, "1") <= 0);
return 0;
}