错误是什么意思是“不能转换类型的价值”?
python代码作为基础:在此处输入链接描述 每个周期发生错误 很多错误(请帮助修复它):
代码:
var t = readLine()!
var s = readLine()!
var len_s = s.count
var t_lis = Set(t)
let character:[Character] = Array(s)
var c_s:[Character: Int] = Dictionary(uniqueKeysWithValues: zip(character, Array(repeating: 1, count: character.count)))
let character2:[Character] = Array(t_lis)
var c_t:[Character: Int] = Dictionary(uniqueKeysWithValues: zip(character2, Array(repeating: 1, count: character2.count)))
var c_res = [String: String]()
var summ = 0
for e in c_s{
c_res[e] = [c_s[e], min( c_s[e], c_t[e] )]
summ += c_res[e][1]}
for i in 0..<((t.count-s.count)+1) {
if summ == len_s-1{
print(i)
break
}
for j in c_res{
if t[i] = c_res[j]{
if c_res[t[i]][1] > 0{
c_res[t[i]][1] -= 1
summ -= 1
}}}
for l in c_res {
if (i+len_s < t.count && t[i+len_s]) = c_res{
if c_res[ t[i+len_s] ][1] < c_res[ t[i+len_s] ][0]{
c_res[ t[i+len_s] ][1] += 1
summ += 1
}}}
}
The Python code was taken as a basis: enter link description here
Errors occur in each cycle
A lot of errors (please help fix it):
Code:
var t = readLine()!
var s = readLine()!
var len_s = s.count
var t_lis = Set(t)
let character:[Character] = Array(s)
var c_s:[Character: Int] = Dictionary(uniqueKeysWithValues: zip(character, Array(repeating: 1, count: character.count)))
let character2:[Character] = Array(t_lis)
var c_t:[Character: Int] = Dictionary(uniqueKeysWithValues: zip(character2, Array(repeating: 1, count: character2.count)))
var c_res = [String: String]()
var summ = 0
for e in c_s{
c_res[e] = [c_s[e], min( c_s[e], c_t[e] )]
summ += c_res[e][1]}
for i in 0..<((t.count-s.count)+1) {
if summ == len_s-1{
print(i)
break
}
for j in c_res{
if t[i] = c_res[j]{
if c_res[t[i]][1] > 0{
c_res[t[i]][1] -= 1
summ -= 1
}}}
for l in c_res {
if (i+len_s < t.count && t[i+len_s]) = c_res{
if c_res[ t[i+len_s] ][1] < c_res[ t[i+len_s] ][0]{
c_res[ t[i+len_s] ][1] += 1
summ += 1
}}}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
作为参考,这是链接到的原始Python代码:
首先,我要提到的是链接到的Python代码非常糟糕。这样,我的意思是没有什么明确命名的。对于要完成的工作,这完全是挑衅的。我敢肯定,如果我说俄语或该页面上的任何内容,这将更清楚,但这不是我所说的。我知道Python编程与Swift编程具有不同的文化,因为Python经常为临时解决方案编写,但实际上应该重构,部分提取了命名良好的功能。这将使它变得更加可读性,并且可能会帮助您将其转化为Swift。我不会尝试在这里进行这些重构,但是一旦解决了错误,如果您想在任何形式的生产环境中使用它,就应该清理它。
正如您所承认的那样,您有很多错误。您询问错误的含义,但大概您想知道如何解决问题,因此我将同时解决这两个问题。错误始于此行:
第一个错误是
无法为类型'string''''''[ny ny]'的值分配
这意味着您正在构建包含类型
yyone的元素的数组
并尝试将其分配给c_res [e]
。c_res
是字典
带有类型字符串
的键和类型String
的值。因此,假设e
是字符串
,它不是 - 在sec中更多地介绍 - 然后c_res [e]
将具有类型值,<代码>字符串。自然的问题是,为什么右侧是
任何
的数组。这取决于数组的定义不是合法的,并且编译器在上面窒息(基本上是其他错误的副产品)。原因是因为min
期望其所有参数都是符合可比
协议的单一类型,但是c_s [e]
和c_s [e]
是非法的...这是因为它们都是dictionary&lt; cartinal int int&gt;
,因此他们期望contric> contrace> contract> contrace ,但是
e
不是字符
。这是一个元组,(字符,int)
。原因要在上一行上找到:因为
c_s
isdictionary&lt; contrac&int&gt;
,其元素是包含targine
的元素int
。对于新手Swift的Python程序员来说,这可能令人惊讶。要迭代键,您必须指定这是您想要的,所以让我们纠正:通过固定的,以前的错误消失了,但是一个新问题已暴露出来。当您在swift中索引
字典
时,您会获得可选值,因为它可能是nil
,如果该键,因此需要解开它。如果您确定
c_s [e]
也不是c_t [e]
将是nil
,您可以这样强制使用它们:但是你确定吗?当然,它们必须是不明显的。 我们需要使用可选的绑定或可选的均值处理可选的。
因此,如果它是
nil
>。请注意, 代码>而不是c_s.keys
,但是现在我们使用元组绑定将键仅分配给e
,而将值分配给csvalue
。这避免了c_s
元素的可选交接。对于c_t [e]
的值,min
仍将返回csvalue
,这似乎是意图。但是我们再次暴露了另一个问题。现在,编译器抱怨我们无法分配
array&lt;
c_res [e]
,它预计为string> String
...在Swift中,字符串
不是array&lt; int&gt;
。我不确定为什么将C_RES
定义为类型String
的值时,当代码放入int
的数组时...重新定义C_RES
。用一个涅rv词来解释“嘿!等等!有一个新的抱怨!”具体来说,
e
是type字符
,但是c_res
isdictionary&lt; string,array&lt&lt; int&gt;&gt;&gt;
,所以让我们只制作c_res
a字典&lt; cartem,array&lt; int&gt;&gt;
而不是。耶!现在,我们已经解决了开始的行上的所有错误...但是现在下一行中有一个:
可选类型的值'[int]?'必须解开包装以参考包装基本类型的成员“下标” [int]'
再次,这是因为当我们将
dictionary
索引时,我们的键
键 /代码>可能不存在。但是,我们只是在调用min
的电话中计算了要添加到summ
的值,所以让我们保存下来并在此处重复使用它。现在,我们终于在第一个循环中没有错误。剩余的错误在嵌套环中。
对于初学者,代码使用
=
来测试平等。与C家族中的所有语言一样,Swift将==
用作平等操作员。我认为在几个地方需要的变化非常简单,因此我不会证明这种迭代。一旦修复了这些问题,我们就会在Swift中获得我最喜欢的(不是)错误:表达式类型是模棱两可的,而没有更多上下文
在此行上:这些模棱两可的错误可能意味着一些事情之一。主要原因是因为表达式的元素匹配了几个定义,并且编译器没有办法弄清楚应该使用哪个定义。这种风味通常伴随着可能的比赛。当多个类型检查失败以编译器无法给出更明显的错误方式时,似乎也会发生这种情况。我认为这是这里发生的版本。此问题的来源返回到外部循环
,该循环使循环变量,
i
,为类型,int
,与使用i
结合使用。要索引t
,即String
。问题在于,您不能用int
将String
索引。您必须使用string.index
。原因归结为字符串
由Unicode字符组成并在内部使用UTF-8,这意味着其字符的长度不同。用int
索引与array
的元素相同的方式将需要O( n )复杂性,但将其索引到一个字符串
有望具有O(1)复杂性。String.Index
通过使用String
index(后面:)
来计算其他索引的索引。基本上将索引到字符串
是一种痛苦,因此在大多数情况下,Swift程序员做其他事情,通常依赖于许多方法String
支持操作。当我写这篇文章时,我还没有汇总代码应该做的事情,这使得在这里很难弄清楚string
方法可能会有所帮助,所以让我们只需转换<代码> t toarray [farne]
,然后我们可以使用整数将其索引到其中:不过,它仍然给出模棱两可的表达错误,因此我查看了Python代码中的等效行。这揭示了翻译中的逻辑错误。这是Python:
没有循环。看起来循环被引入模拟检查,以查看
t [i]
是否在c_res
中,这是一种方法,但这是错误的。 Swift可以更简洁地做到这一点:但是我们可以使用可选的绑定来进一步清洁它:
但是,我们再次将索引到
字典
返回需要在行上取消包装的可选式的问题,幸运的是,我们刚刚确保将
c_res [tchar]
绑定到cresvalue
时,我们需要再次索引的唯一原因是,因为我们需要更新字典值...这是一个很好的使用力 - unwrap:最后一个循环似乎也是测试
c_res
中存在的结果,并且循环变量甚至都没有使用。这是原始的python:我们可以在此处使用可选的绑定与comma-if语法和另一种力 - 纳普。
当然,由于我们使用新值重新使用
tchar
,因此必须从let
更改为var
。现在一切都编译了。它肯定需要重构,但是这里完全是:
如果所有这些让您想知道为什么有人会使用这种挑剔的语言,那么有两件事要考虑。首先是,最初以SWIFT编写代码,甚至从另一种强烈键入的语言翻译时,您不会遇到太多错误。从python等无打字语言中涵盖的是一个问题,因为除了细微的其他差异之外,您还必须将其固定在某种混凝土类型中的过于灵活的数据视图 - 并不总是很明显。另一件事是,强烈键入的语言使您能够尽早捕获大量的错误……因为类型系统甚至不允许它们编译。
For reference, here is the original Python code that OP linked to:
First I want to mention that the Python code that was linked to is pretty bad. By that, I mean that nothing is clearly named. It's totally obtuse as to what it's trying to accomplish. I'm sure it would be clearer if I spoke Russian or whatever the languge on that page is, but it's not either of the ones I speak. I know Python programming has a different culture around it than Swift programming since Python is often written for ad hoc solutions, but it really should be refactored, with portions extracted into well-named functions. That would make it a lot more readable, and might have helped you in your translation of it into Swift. I won't try to do those refactorings here, but once the errors are fixed, if you want to use it in any kind of production environment, you really should clean it up.
As you acknowledge, you have a lot of errors. You ask what the errors mean, but presumably you want to know how to fix the problems, so I'll address both. The errors start on this line:
The first error is
Cannot assign value of type '[Any]' to subscript of type 'String'
This means you are building an array containing elements of type
Any
and trying to assign it toc_res[e]
.c_res
isDictionary
with keys of typeString
and values of typeString
. So assuminge
were aString
, which it isn't - more on that in a sec - thenc_res[e]
would have the type of the value, aString
.The natural question would be why is the right-hand side an array of
Any
. It comes down to the definition of the array isn't legal, and the compiler is choking on it (basically, a by-product of other errors). The reason is becausemin
expects all of its parameters to be of a single type that conforms to theComparable
protocol, butc_s[e]
andc_s[e]
are illegal... and that's because they are bothDictionary<Character, Int>
, so they expect an index of type ofCharacter
, bute
isn't aCharacter
. It's a tuple,(Character, Int)
. The reason is to be found on the preceding line:Since
c_s
isDictionary<Character, Int>
it's elements are tuples containing aCharacter
and anInt
. That might be surprising for a Python programmer new to Swift. To iterate over the keys you have to specify that's what you want, so let's correct that:With that fixed, previous errors go away, but a new problem is exposed. When you index into a
Dictionary
in Swift you get an optional value, because it might benil
if there is no value stored for thatkey
, so it needs to be unwrapped. If you're sure that neitherc_s[e]
norc_t[e]
will benil
you could force-unwrap them like this:But are you sure? It's certainly not obvious that they must be. So we need to handle the optional, either with optional binding, or optional coallescing to provide a default value if it is
nil
.`Note that we've gone back to iterating over
c_s
instead ofc_s.keys
, but now we're using tuple binding to assign just the key toe
and the value tocsValue
. This avoids optional handing forc_s
elements. For the value fromc_t[e]
I use optional coallescing to default it to the maximum integer, that way ifc_t[e]
isnil
,min
will still returncsValue
which seems to be the intent.But again we have exposed another problem. Now the compiler complains that we can't assign
Array<Int>
toc_res[e]
which is expected to be aString
... In Swift,String
is not anArray<Int>
. I'm not sure whyc_res
is defined to have values of typeString
when the code puts arrays ofInt
in it... so let's redefinec_res
.To paraphrase a Nirvana lyric, "Hey! Wait! There is a new complaint!" Specifically,
e
is typeCharacter
, butc_res
isDictionary<String, Array<Int>>
, so let's just makec_res
aDictionary<Character, Array<Int>>
instead.Yay! Now we've resolved all the errors on the line we started with... but there's now one on the next line:
Value of optional type '[Int]?' must be unwrapped to refer to member 'subscript' of wrapped base type '[Int]'
Again this is because when we index into a
Dictionary
, the value for ourkey
might not exist. But we just computed the value we want to add tosumm
in our call tomin
, so let's save that off and reuse it here.Now we finally have no errors in the first loop. Remaining errors are in the nested loops.
For starters, the code uses
=
to test for equality. As with all languages in the C family, Swift uses==
as the equality operator. I think that change, which is needed in couple of places, is pretty straight forward, so I won't show that iteration. Once those are fixed, we get one of my favorite (not) errors in Swift:Type of expression is ambiguous without more context
on this line:These ambiguity errors can mean one of a few things. The main reason is because elements of the expression match several definitions, and the compiler doesn't have a way to figure out which one should be used. That flavor is often accompanied by references to the possible matches. It also seems to happen when multiple type-check failures combine in a way the compiler can't give a clearer error. I think that's the version that's happening here. The source of this problem goes back to the outer loop
which makes the loop variable,
i
, be of type,Int
, combined with usingi
to index intot
, which is aString
. The problem is that you can't index intoString
with anInt
. You have to useString.Index
. The reason comes down toString
consisting of unicode characters and using UTF-8 internally, which means that it's characters are of different lengths. Indexing with anInt
in the same way as you would for an element of anArray
would require O(n) complexity, but indexing into aString
is expected to have O(1) complexity.String.Index
solves this by usingString
methods likeindex(after:)
to compute indices from other indices. Basically indexing into aString
is kind of pain, so in most cases Swift programmers do something else, usually relying on the many methodsString
supports to manipulate it. As I'm writing this, I haven't yet put together what the code is supposed to be doing, which makes it hard to figure out whatString
methods might be helpful here, so let's just convertt
toArray[Character]
, then we can use integers to index into it:That still gives an ambiguous expression error though, so I looked at the equivalent line in the Python code. This revealed a logic error in translation. Here's the Python:
There is no loop. It looks like the loop was introduced to mimic the check to see if
t[i]
is inc_res
, which is one way to do it, but it was done incorrectly. Swift has a way to do that more succinctly:But we can use optional binding to clean that up further:
But again we have the problem of indexing into a
Dictionary
returning an optional which needs unwrapping on the line,Fortunately we just ensured that
c_res[tChar]
exists when we bound it tocResValue
, and the only reason we need to index into again is because we need to update the dictionary value... this is a good use of a force-unwrap:The last loop also seems to be the result of testing for existence in
c_res
and the loop variable isn't even used. Here's the original Python:We can use optional binding here combined with the comma-if syntax, and another force-unwrap.
Of course, since we're re-using
tChar
with a new value, it has to be changed fromlet
tovar
.Now it all compiles. It definitely needs refactoring, but here it is altogether:
If all of this makes you wonder why anyone would use such a picky language, there are two things to consider. The first is that you don't get so many errors when writing code originally in Swift, or even when translating from another strongly typed language. Coverting from a typeless language, like Python, is a problem, because apart from subtle other differences, you also have to pin down it's overly flexible view of data to some concrete type - and that's not always obvious how to do it. The other thing is that strongly typed languages allow you to catch huge classes of bugs early... because the type system won't even let them compile.