我有以下问题:
我需要解码整数序列" c"字符串消息" m"通过以下关联:
numpos = 10 % ( = size(c,2)/2)
c = [3 4 1 1 4 2 5 2 3 3,1 1 1 1 2 2 2 3 3 3]
每一行" c"表示2 * numpos整数,其中第一个numpos参数编码位置
types = {'a' 'b@2' 'c@6' 'd@10' 'e@11'}
仅当类型包含字符' @'时才应用和第二个numpos参数。像这样:
m = ' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
我目前的解决方案如下:
function m = c2m(c,types)
numpos = size(c,2)/2;
F = cellfun(@(f) [' ' f], strrep(types,'@',':%d@'),'unif',0);
m = arrayfun(@(f,k) sprintf(f{1},k),F(c(:,1:numpos)),c(:,numpos+(1:numpos)),'unif', 0);
m = arrayfun(@(i) horzcat(m{i,:}), (1:numlines)', 'unif', 0)
end
,测试代码如下:
numlines = 10;
c = repmat([3 4 1 1 4 2 5 2 3 3,1 1 1 1 2 2 2 3 3 3],numlines,1);
types = {'a' 'b@2' 'c@6' 'd@10' 'e@11'};
m = c2m(c,types);
m =
10×1 cell array
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
{' c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'}
代码对我来说仍然太慢,我正在寻找任何加速。在这种情况下,CPU时间的最重要部分用于内置函数" sprintf"。
典型的实际问题是:
numpos ~ 30 ... 60
numlines ~ 1e4 ... 1e5
有什么想法吗?
答案 0 :(得分:2)
在16b中,MATLAB发布了一些新的文本函数,使这很容易。同样在16b中,MATLAB提供了新的字符串数据类型,使其更快。
function m = c2m_new(c,types, numlines)
types = string(types);
num_values = size(c,2)/2;
a = c(:,1:num_values);
b = c(:,(num_values+1):end);
m = types(a);
m = insertBefore(m,"@", ":" + b);
m = join(m,2);
end
>> numlines = 10;
>> c = repmat([3 4 1 1 4 2 5 2 3 3,1 1 1 1 2 2 2 3 3 3],numlines,1);
>> types = {'a' 'b@2' 'c@6' 'd@10' 'e@11'};
>> c2m_new(c,types,numlines)
ans =
10×1 string array
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
"c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6"
观察表现:
>> numlines = 1E4;
>> c = repmat([3 4 1 1 4 2 5 2 3 3,1 1 1 1 2 2 2 3 3 3],numlines,1);
>> types = {'a' 'b@2' 'c@6' 'd@10' 'e@11'};
% My solution
>> tic; for i = 1:10; c2m_new(c,types, numlines); end; toc
Elapsed time is 0.669311 seconds.
% michalkvasnicka's solution
>> tic; for i = 1:10; c2m(c,types, numlines); end; toc
Elapsed time is 23.643991 seconds.
% gnovice's solution
>> tic; for i = 1:10; c2m_gnovice(c,types, numlines); end; toc
Elapsed time is 8.960392 seconds.
答案 1 :(得分:0)
这是一个开始尝试的想法。
from tkinter import *
class main(Frame):
def __init__(self, master=None):
super(main, self).__init__(master)
self.grid()
self.pack()
def buttons_dash():
# create first button
self.bttn1_dash = Button(self, text = "Student Login",)
self.bttn1_dash.grid()
self.bttn1_dash.config(height=3, width=30)
# create second button
self.bttn2_dash = Button(self)
self.bttn2_dash.grid()
self.bttn2_dash.configure(text = "Staff Login")
self.bttn2_dash.config(height=3, width=30)
# create third button
self.bttn3_dash = Button(self)
self.bttn3_dash.grid()
self.bttn3_dash["text"] = "Exit"
self.bttn3_dash.config(height=3, width=30)
self.bttn3_dash = Button(self, text= "Exit")
class student_dashboard(Frame):
def __init__(self, master=None):
super(main, self).__init__(master)
self.grid()
self.pack()
def buttons_student():
#create first button
self.bttn1_student = Button(self, text = "View Highscores")
self.bttn1_student.grid()
self.bttn1_student.config(height=3, width=30)
# create second button
self.bttn2_student = Button(self)
self.bttn2_student.grid()
self.bttn2_student.configure(text = "Save Score")
self.bttn2_student.config(height=3, width=30)
# main
root = Tk()
root.title("Dashboard")
app = main(root)
root.mainloop()
然后
numpos = 10 % ( = size(c,2)/2)
c = [3 4 1 1 4 2 5 2 3 3,1 1 1 1 2 2 2 3 3 3];
types = {'a' 'b@2' 'c@6' 'd@10' 'e@11'}
给出了
m = 1×10单元阵列 第1至10栏
{'c:1 @ 6'} {'d:1 @ 10'} {'a:1 @ 0'} {'a:1 @ 0'} {'d:2 @ 10'} {' b:2 @ 2'} {'e:2 @ 11'} {'b:3 @ 2'} {'c:3 @ 6'} {'c:3 @ 6'}
答案 2 :(得分:0)
这是您c2m
功能的替代方案,比上面列出的numpos
和numlines
的典型范围快2至3倍:
function m = c2m(c, types)
numpos = size(c, 2)/2;
[pre, post] = strtok(types(c(:, 1:numpos)), '@');
mid = strsplit(sprintf(' :%i', 1:max(max(c(:, numpos+1:2*numpos)))));
mid = mid(c(:, numpos+1:2*numpos).*~cellfun(@isempty, post)+1);
m = cellstr(char(join(strcat(pre, mid, post))));
end
首先,使用strtok
在c
分割'@'
的前半部分。然后创建包含字符串mid
的单元格数组{'' ':1' ':2' ... ':N'}
,其中N
是c
的后半部分中找到的最大值。这允许我们通过简单地索引到mid
以获取字符串来避免应用于整个矩阵的昂贵转换函数(如sprintf
,num2str
,int2str
等)想。索引只是c
的右半部分乘以表示'@'
是否存在的逻辑数组(使用cellfun
获得)并递增1。
最后,使用strcat
连接三个不同的字符串(pre
,mid
和post
),使用join
逐行收集到字符串中(自R2016b起出现),然后转换为具有cellstr
和char
的字符数组的单元格数组。
使用以下值对其进行测试:
numpos = 10;
numlines = 10;
c = repmat([3 4 1 1 4 2 5 2 3 3,1 1 1 1 2 2 2 3 3 3], numlines, 1);
types = {'a' 'b@2' 'c@6' 'd@10' 'e@11'};
我们得到了理想的结果:
m =
10×1 cell array
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'
'c:1@6 d:1@10 a a d:2@10 b:2@2 e:2@11 b:3@2 c:3@6 c:3@6'