Java 给定一个数字,检查数字是否与加法形成等式?

Java 给定一个数字,检查数字是否与加法形成等式?,java,c++,algorithm,math,Java,C++,Algorithm,Math,给定一个字符串S,我想知道S中是否有不重叠的子字符串a、B和C,这样当子字符串被解释为十进制数时,方程a+B=C成立 例如:对于S=17512,答案是肯定的,因为12+5=17成立 这不是一个家庭作业问题,我尝试过解决这个问题,构建一个后缀数组 17512年 7512 512 十二, 二, 但后来我意识到,给定132,1+2=3 在选择中是否需要其他形式的排列 如何有效地解决这个问题?如果允许按原始给定顺序从任意数字子集形成子字符串,只要你的数字在2个求和和和中不重叠,那么我相信你的问题是NP完

给定一个字符串S,我想知道S中是否有不重叠的子字符串a、B和C,这样当子字符串被解释为十进制数时,方程a+B=C成立

例如:对于S=17512,答案是肯定的,因为12+5=17成立

这不是一个家庭作业问题,我尝试过解决这个问题,构建一个后缀数组

17512年

7512

512

十二,

二,

但后来我意识到,给定132,1+2=3 在选择中是否需要其他形式的排列


如何有效地解决这个问题?

如果允许按原始给定顺序从任意数字子集形成子字符串,只要你的数字在2个求和和和中不重叠,那么我相信你的问题是NP完全的。我认为,如果给定了目标和,你所要做的就是找到两个不重叠的数字子串,它们加起来就是目标和,这也是正确的。然而,我还没有NP完全性的证明

如果数字的子串必须是连续的,那么情况会好得多。您可以在O(n^6)时间内搜索2个求和和和1个求和的所有组合中的数字的起点和终点,当然可以进行改进,因为例如,对于给定的目标求和,您只需要搜索一对子字符串,这些子字符串的最大长度加起来等于目标和的长度,或者正好等于或减去1

更新:如果您需要找到3个非重叠的连续子字符串来给出求和公式,那么您可以对所有O(n^2)子字符串值进行散列,然后对所有求和数对的和进行散列,以查看目标和是否在哈希表中。如果是这样,那么您只需要检查summand、开始索引和结束索引是否与summand索引重叠。最坏情况下的时间是O(n^6),随机输入的预期运行时间是O(n^5)。

让我们用十进制表示数字。如果n=| S |足够小(B)。我们知道它们需要大约相同的大小(正/负一位数),因此枚举可能性是一个立方运算(有O(n3)个候选)

对于每个候选对(A,C),我们需要检查
B=C-A
是否在字符串中,并且是否与任何A或C子字符串重叠。我们可以使用以10为基数的算法计算线性时间差

棘手的部分是检查B是否是不重叠a或C的子字符串。a和C将字符串分为3部分:

S = xAyCz
如果我们以一种巧妙的方式列举它们,在固定起始位置和减小尺寸的情况下,我们可以保持x部分和y、z部分的相反方向

现在我们可以在线性时间中检查三个部分中的一个是否存在B=C-A(或其相反)

这种方法的时间复杂度:Θ(n4)

这其中有一个变化,稍微复杂一点,但速度更快(感谢叶甫根尼指出):

  • 创建输入字符串的后缀树。每个节点代表一个子字符串。在每个节点中存储一个平衡的二进制搜索树,其中包含子字符串在字符串中出现的位置。这里可能需要持久化的树来节省时间和空间
  • 枚举A和C,但这次从最低有效位(最右端)开始
  • 当A和C从右向左增长时,跟踪B=C-A的结果。它也将从最不重要的数字增长到最重要的数字。在后缀树中搜索B。您可以一次执行一个数字,因此您可以使a和C增长1个数字,更新B并将其定位在O(1)中的后缀树中
  • 如果B为正,则在位置的BBST中进行三次范围查询,以检查B是否出现在字符串中且不与A或C重叠
运行时:O(n3日志n)

更新:关于需要使用所有字符的简化版本:

我们首先意识到,如果以10为基数,我们可以在线性时间内对字符串的子字符串进行算术运算

现在我们要找到分裂点a 我们可以证明a和b的候选者数量是恒定的,因为所有三个部分都必须具有近似相同的大小才能保持方程

使用任意精度的算法,我们可以很容易地尝试所有候选对(a,b),并且对于每个候选对,找到M=max(a,b,C)。然后检查M是否是其他两个数字的和


总时间复杂度:Θ(n)。

假设(在两个示例中)您的3个子串是连续的、非重叠的、非负的,并且它们之间覆盖了整个输入,则存在二次时间解

  • 首先(暂时)假设订单为aaabbbccc,其中aaa+bbb=ccc,aaa>bbb
  • ccc的长度必须与aaa相同或最多一个更大
  • 因此,aaa(len_a)的长度必须介于n/3和n/2之间
  • 给定len_a,len_c有两种选择——len_a或len_a+1
  • 考虑到这些,只有一种可能的bbb长度。len_b=n-len_a=len_c
  • 测试这2个(n/2-n/3)=n/3个案例
  • 由于字符串到int的转换,每个测试都是O(n)成本
对两种排列(aaa>bbb v bbb>=aaa)重复上述分析,乘以三种排列(aaa+bbb=ccc v aaa+ccc=bbb v bbb+ccc=aaa)

您可以改进测试,只检查三个数字中的最高(或最低)有效i位,如果无法求和,则提前返回。假设随机分布的数字,您可能能够显示这样一个测试的预期运行时间是恒定的。
这将使整个算法变成一个O(n)运行时。

你是否也能得到1+7=5+1+2?等式中是否所有数字都必须存在?而且,
12
不是数字。你能把数字填出来吗