给定间隔的随机字符串

时间:2019-05-19 15:16:07

标签: c string random

我想用这个签名创建一个函数

char *generateString(char *par1, char *par2);

结果应为严格大于par1(与strcmp比较且小于par2的字符串。 Par1和Par2的长度在0到MAX之间。

[INF,SUP]间隔之间选择每个字符。 (参数是由这些字符组成的字符串。)

字符串的长度是有限的,但也可以在0到某个最大值之间随机变化。

似乎很难编写代码,任何人都可以提供帮助?

1 个答案:

答案 0 :(得分:0)

该问题要求输入一个排除范围内的随机字符串。下面的解决方案给出了一个包含范围的随机字符串。解决包含范围问题要容易得多。如果我们想要一个排他范围,我们只是拒绝生成的字符串(如果它位于范围的边界上),并生成另一个随机字符串,直到不在范围的边界上为止。我为此添加了功能randstrx()

为说明我的解决方案,我们考虑十进制数字的字符串,即其字符在C = [0 9]范围内。例如,任意长度的0012766501231等。考虑给定长度的所有字符串,例如4。显然,这些字符串上存在顺序。例如,对于我们的十进制数字字符串,长度为4的字符串按以下顺序排序:000000010002,...,9999

给出给定长度的任何字符串,很容易以字符串顺序计算紧随其后或之前的相同长度的字符串(我们将忽略在字符串之后或之前不存在的两种边界情况,因为不需要它们)。对于我们的十进制数字字符串,我们只需添加或减去1。加法和减法在任何基数中都有很好的定义,数字可以由任何符号组成,它们不必是十进制数字。因此,这定义了如何在给定长度的任何字符串上添加或减去1(或一个单位)。我们将在下面使用它。

S1S2分别是字符串范围的上限和下限。我们有S1 <= S2;顺序由strcmp()定义。 L1S1的长度,而L2S2的长度。我们要生成S范围内的随机字符串[S1 S2]S的长度可以为L <= M,其中M是给定的常数。所有字符串都包含C = [C1 C2]范围内的字符。

[步骤1] 第一步包括为L生成一个随机长度S。根据{{​​1}}和S1的值,并非所有长度都可能。实际上,S2S1可以以相同的字符序列开头,例如在S2[123555 1237]S1中都以S2开头。假设长度为123的{​​{1}}是在SkK >= 0开头的等号序列。令S1S2,其中S1 = Sk + T1S2 = Sk + T2分别是T1T2Sk之后的字符序列,并且S1是字符串串联运算符。令S2+分别为N1 >= 0N2 >= 0的长度。我们考虑了4种情况:

  • T1T2在这种情况下,为N1 = 0,因此范围N2 = 0包含单个字符串S1 = S2 = Sk长度为[S1 S2]。因此,SkK的唯一可能值。
  • L = KL这种情况是不可能的,因为我们假设N1 > 0
  • N2 = 0S1 <= S2显然,N1 = 0必须至少N2 > 0个公共字符序列的长度{{1} }}和L。要确定K的上限,我们需要考虑S1。如果S2可以递减,则意味着我们可以生成小于L的任意长度的字符串。例如,如果T2T2,则S2小于S1 = 123(和S2 = 123001)。 12300099...9不能递减的唯一情况是S2时。例如,如果> S1T2,则T2 = C1 + C1 + ... + C1不能递减。无法生成小于S1 = 123且长度大于S2 = 123000的字符串。因此,在这种情况下,T2必须在S2范围内。
  • L2L考虑[K L2]的上限。我们知道N1 > 0以及N2 > 0L的首字符不相等,如果相等,则共同的首字符将以共同的起始序列T1 < T2开头。这意味着可以T1递增或T2递减。实际上,例如,在我们的十进制数字字符串中,唯一不能递增的SkT1。如果T2等于此值,那么它也必须是T1的值,但是99...9等于T1T2T1必须位于T2中,这是一个矛盾。可以对T1执行类似的推理。唯一不能递减的T2Sk,因此T2也必须是T2,这会将T2 = 00...0T1放入00...0,这是一个矛盾。因为T1可以递增,T2可以递减,所以我们可以生成随机字符串或大于Sk且小于T1的任意长度。例如,如果T2T1,则字符串T2S1 = 1231属于S2 = 1234范围。考虑12311...1的下限。长度为123399...9的任何字符串都必须等于[S1 S2],但是由于LK小于Sk。因此,随机字符串的长度不能为N1 > 0。但是,很容易表明它的长度可以为Sk。我们知道S1的第一个字符K小于K + 1的第一个字符,并且可以递增。因此,附加有字符T1[0]的字符串T1是长度为T2的字符串,其长度大于Sk。它也小于或等于T1[0] + 1。实际上,如果K + 1S1,则随机字符串等于S2。向T2[0] = T1[0] + 1添加更多字符只会使N2 = 1比随机字符串大。因此,S2必须大于或等于S2

总而言之,我们有:

  • 对于S2LK + 1
  • 对于N1 = 0N2 = 0L = K
  • 对于N1 > 0N2 > 0,如果L > K则为N1 = 0,否则为N2 > 0

鉴于上述情况,我们为L = [K L2]生成了一个随机值T2 = 00...0

[步骤2] ,我们计算长度为L >= K的最小字符串L,该字符串大于或等于S。如果S1L,则L附加S1个字符,使其长度等于L >= L1。例如,如果S1LS1,而C1L,则S1。另一方面,如果23906,我们将L截短为长度8,并如上所述添加S1L = 23906000。例如,如果L < L1S1,而L1,则S1

[步骤3] ,我们计算长度为23906且小于或等于L的最大字符串3。如果S1L = 240,则S2LL减去S2(如上所述)并附加了足够的L > L2个字符,以使其长度等于S2L 。例如,如果S21,而C2L,则S2。另一方面,如果23906,我们将L截短为长度8。例如,如果S2L = 23905999L < L2,而S2L,则S2

[步骤4] 现在,我们同时拥有长度在23906范围内的最小和最大字符串,L,很容易生成一个随机字符串长度3在相同范围内。我们只需将S2L = 239L中的每个[S1 S2]的{​​{1}}设置为L范围内的随机字符值。

这是实现该解决方案的C代码。

S[i]