我有一些带整数的字符串(一个字符串中的2到5个数字,用空格分隔)这是一个例子:
1 4 5 19
1 5
2 3 6 59
2 6
3 2 4 60
3 4
4 1 3 61
4 3
25 13 23 64 65
13 18
14 13 15 75
14 15
15 14 16 76
15 14
45 44 102 103 104
我需要重复地将所有数字增加129,所以开头将是:
130 133 134 148
130 134
131 132 135 188 ...
接下来的增加将是:
259 262 263 277
259 263
260 261 264 317 ...
此类字符串分析的最佳选择是什么? 首先计算数字,然后使矩阵填充“0”:[0,0,0,0,0] 比填充它 - 它将是: 第1行[1,4,5,19, 0 ] 第2行[1,5, 0 , 0 , 0 ]
并增加所有不为零的数字。 我正在考虑正确方向的这项任务的解决方案还是有更简单的方法? 或者有任何现成的解决方案,我只是不明白如何准确搜索它?
结果必须采用特定格式 - it is PDB file CONECT records。
答案 0 :(得分:2)
如果您知道最终尺寸,则可以预先分配一个numpy数组的零。说出您最初要处理每一行的方式(SwingUtilities.invokeAndWait
),然后对文件中的每一行(process_row
)执行此操作。
process_file
答案 1 :(得分:2)
一个Tcl,如果你只需要加起来的数字:
set text { 1 4 5 19
1 5
2 3 6 59
2 6
3 2 4 60
3 4
4 1 3 61
4 3
25 13 23 64 65
13 18
14 13 15 75
14 15
15 14 16 76
15 14
45 44 102 103 104}
proc addevery {txt amount} {
# Creating an alias so we can modify the variable from outside the proc
upvar text gtext
set result [list]
# Split to get lines
foreach line [split $txt \n] {
set lineresult [list]
# Get each number added
foreach item [regexp -all -inline {\S+} $line] {
lappend lineresult [expr {$item+$amount}]
}
lappend result $lineresult
}
set gtext [join $result \n]
puts $gtext
return
}
puts "Adding 129:"
addevery $text 129
puts "\nAdding again 129:"
addevery $text 129
编辑:在了解潜在问题之后;我们必须保持格式化(更具体地说,在每一系列数字之前添加CONECT
,使数字保持5个空格右缩进格式,并能够输出添加到原始数据的不同“步骤”同一个文件中的数字。最后一件事,第一次迭代实际上不应该向原始数字添加任何东西。
set fin [open "Input.txt" r]
set fout [open "Output.txt" w]
set lines [split [read $fin] "\n"]
# Amount to be added each time
set amount 129
# Number of times to be added
set times 100
proc addevery {amount} {
global lines
# Result list
set lresult [list]
foreach line $lines {
# Result line
set result {}
# Get every 5 chars of the line
foreach item [regexp -all -inline {.{5}} $line] {
# Add, format then append to result line
append result [format %5s [expr {[string trim $item]+$amount}]]
}
# Add line to the result list
lappend lresult $result
}
# Set the lines to the new lines
set lines $lresult
return $lresult
}
for {set i 0} {$i < $times} {incr i} {
# If 0, put the original with CONECT
if {$i == 0} {
puts $fout [join [lmap x $lines {set x "CONECT$x"}] "\n"]
} else {
puts $fout [join [lmap x [addevery $amount] {set x "CONECT$x"}] "\n"]
}
}
close $fin
close $fout
作为奖励,python相当于:
amount = 129
times = 100
import re
def addevery(amount):
global lines
lresult = []
for line in lines:
result = ''
for item in re.findall(r'.{5}', line):
result += "%5s" % (int(item.strip()) + amount)
lresult.append(result)
lines = list(lresult)
return lresult
with open('Input.txt', 'r') as fin:
with open('Output.txt', 'w') as fout:
lines = fin.read().split('\n')
for i in range(0,times):
if i == 0:
fout.write('\n'.join(['CONECT'+i for i in lines]) + '\n')
else:
fout.write('\n'.join(['CONECT'+i for i in addevery(amount)]) + '\n')
答案 2 :(得分:1)
你正在寻找一个二维数组(它是一个矩阵)。
首先,你可以用0来初始化它:
Matrix = [[0 for x in range(20)] for x in range(5)]
您必须更改所需尺寸的数量。 20是行数,5是列数。
之后,你可以将数字放在你想要的位置,使用:
Matrix[r][c] = 1
同样,R是行,C是列。
如果你想在开始时填充矩阵,你也可以选择:
Matrix = [ [1, 4, 5, 19, 0], [1, 5, 0, 0, 0], [0, 0, 0, 0, 0],
[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] ]
然后在彼此内部使用两个for循环来增加数字
for i in range(20):
for j in range(5):
Matrix[i][j] = Matrix[i][j] + 129
答案 3 :(得分:1)
一些Tcl解决方案。假设带有数字的原始文本位于变量str
中,请参见下文。
执行此操作的一种方法是将所有数字替换为命令调用以进行计算,然后对字符串执行替换(格式化将稍微关闭,因为数字现在会更宽,但空格保持不变):
set res [subst [regsub -all {\d+} $str {[expr {&+129}]}]]
另一种方法是将字符串拆分为行和数字的矩阵并遍历它:
set res {}
foreach line [split $str \n] {
foreach n $line {
append res [format %5s [incr n 129]]
}
append res \n
}
使用Tcl 8.6 lmap
映射命令的相同方法:
set res [join [lmap line [split $str \n] {
join [lmap n $line {
format %5s [incr n 129]
}] {}
}] \n]
在这两种情况下,结果字符串都将位于变量res
中,并保留原始格式。
ETA:右对齐输出:
set res [join [lmap line [split $str \n] {
format %25s [join [lmap n $line {
format %5s [incr n 129]
}] {}]
}] \n]
变量str
像这样分配,作为纯文本(在末尾修剪换行符以避免空鬼元素):
set str [string trim {
1 4 5 19
1 5
2 3 6 59
2 6
3 2 4 60
3 4
4 1 3 61
4 3
25 13 23 64 65
13 18
14 13 15 75
14 15
15 14 16 76
15 14
45 44 102 103 104
} \n]
文档:append,expr,foreach,format,incr,lmap,regsub,{{3 }},set,split,string
答案 4 :(得分:1)
Tcl: requires Tcl 8.6 for lmap
package require Tcl 8.6
# list of strings
set strings {
{ 1 4 5 19}
{ 1 5}
{ 2 3 6 59}
{ 2 6}
{ 3 2 4 60}
{ 3 4}
{ 4 1 3 61}
{ 4 3}
{ 25 13 23 64 65}
{ 13 18}
{ 14 13 15 75}
{ 14 15}
{ 15 14 16 76}
{ 15 14}
{ 45 44 102 103 104}
}
proc incr_all {listvar {n 1}} {
upvar 1 $listvar lst
set lst [lmap sublist $lst {lmap elem $sublist {expr {$elem + $n}}}]
}
proc format_strings {lst} {
join [lmap sublist $lst {format [string repeat {%5s} [llength $sublist]] {*}$sublist}] \n
}
incr_all strings 119
puts [format_strings $strings]
output
120 123 124 138
120 124
121 122 125 178
121 125
122 121 123 179
122 123
123 120 122 180
123 122
144 132 142 183 184
132 137
133 132 134 194
133 134
134 133 135 195
134 133
164 163 221 222 223
答案 5 :(得分:1)
set incriment 127
set molecules 450
set fout [open "Results.txt" w]
close $fout
proc addevery {filein fileout amount times} {
set fh [open $filein r]
set fout [open $fileout a+]
while {[gets $fh line] != -1} {
set result {}
foreach item [regexp -all -inline {.{5}} $line] {
append result [format %5s [expr {[string trim $item]+($amount*$times)}]]
}
puts $fout "CONECT$result"
}
close $fh
close $fout
}
for {set i 0} {$i < $molecules} {incr i} {
addevery "Connections_.txt" "Results.txt" $incriment $i
}
感谢https://stackoverflow.com/users/1578604/jerry 它工作正常,但尚未优化。