给定一个二维的m x n数组,如何以逆时针方式遍历它们?
例如:
// ./~/detect-private-browsing/index.js
function retry(isDone, next) {
var current_trial = 0, max_retry = 50, interval = 10, is_timeout = false;
var id = window.setInterval(
function() {
if (isDone()) {
window.clearInterval(id);
next(is_timeout);
}
if (current_trial++ > max_retry) {
window.clearInterval(id);
is_timeout = true;
next(is_timeout);
}
},
10
);
}
function isIE10OrLater(user_agent) {
var ua = user_agent.toLowerCase();
if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
return false;
}
var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
if (match && parseInt(match[1], 10) >= 10) {
return true;
}
// MS Edge Detection from this gist: https://gist.github.com/cou929/7973956
var edge = /edge/.exec(ua);
if (edge && edge[0] == "edge") {
return true;
}
return false;
}
module.exports = {
detectPrivateMode: function(callback) {
var is_private;
if (window.webkitRequestFileSystem) {
window.webkitRequestFileSystem(
window.TEMPORARY, 1,
function() {
is_private = false;
},
function(e) {
console.log(e);
is_private = true;
}
);
} else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
var db;
try {
db = window.indexedDB.open('test');
} catch(e) {
is_private = true;
}
if (typeof is_private === 'undefined') {
retry(
function isDone() {
return db.readyState === 'done' ? true : false;
},
function next(is_timeout) {
if (!is_timeout) {
is_private = db.result ? false : true;
}
}
);
}
} else if (isIE10OrLater(window.navigator.userAgent)) {
is_private = false;
try {
if (!window.indexedDB) {
is_private = true;
}
} catch (e) {
is_private = true;
}
} else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
// One-off check for weird sports 2.0 polyfill
// This also impacts iOS Firefox and Chrome (newer versions), apparently
// @see bglobe-js/containers/App.js:116
if (window.safariIncognito) {
is_private = true;
} else {
try {
window.openDatabase(null, null, null, null);
} catch (e) {
is_private = true;
}
try {
window.localStorage.setItem('test', 1);
} catch(e) {
is_private = true;
}
}
if (typeof is_private === 'undefined') {
is_private = false;
window.localStorage.removeItem('test');
}
}
retry(
function isDone() {
return typeof is_private !== 'undefined' ? true : false;
},
function next(is_timeout) {
callback(is_private);
}
);
}
};
我真的不介意是用ruby还是js给出实现
我当前的解决方案是这样的:
matrix = [
[ 1, 2, 3, 4 ],
[ 5, 6, 7, 8 ],
[ 9, 10, 11, 12 ],
[ 13, 14, 15, 16 ]
]
1st loop: 1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2
2nd loop: 6, 10, 11, 7, 6
只要格式正确,输出就不会格式化。
此问题的目的是逆时针逐层遍历这些数组,直到没有更多层为止。对于每个遍历,我们将值逆时针移动。例如:
(1..rotate).each do
bottom_left_corner = i
top_right_corner = j
start_nth_layer = 1; end_nth_layer = matrix.length - 2
matrix.reverse_each do
matrix[bottom_left_corner].unshift(matrix[bottom_left_corner - 1].shift) if bottom_left_corner > 0
matrix[top_right_corner] << matrix[top_right_corner + 1].pop if top_right_corner < matrix.length - 1
bottom_left_corner -= 1; top_right_corner += 1
end
nth_layer(matrix, start_nth_layer, end_nth_layer)
end
答案 0 :(得分:0)
这是矩阵图层旋转问题。这是我的完整解决方案:
function matrixRotation(matrix, rotate) {
var r = matrix.length, c = matrix[0].length;
var depth = Math.min(r,c)/2;
for(var i=0;i<depth;i++) {
var x = i, y = i, n = (r-i*2 - 2)*2 + (c-i*2-2)*2+4, dir = 'down', index=0;
var buf = [];
while(index < n) {
buf.push(matrix[x][y]);
if(dir == 'down') {
if(x+1 >= r-i) {
dir = 'right';
y++;
} else {
x++;
}
} else if(dir == 'right') {
if(y+1 >= c-i) {
dir = 'up';
x--;
} else {
y++;
}
} else if(dir == 'up') {
if(x-1 <= i-1) {
dir = 'left';
y--;
} else {
x--;
}
} else if(dir == 'left') {
y--;
}
index++;
}
var move = rotate%n;
buf = [...buf.slice(buf.length-move), ...buf.slice(0, buf.length-move)]
x = i, y = i, dir = 'down', index = 0;
while(index < n) {
matrix[x][y] = buf[index];
if(dir == 'down') {
if(x+1 >= r-i) {
dir = 'right';
y++;
} else {
x++;
}
} else if(dir == 'right') {
if(y+1 >= c-i) {
dir = 'up';
x--;
} else {
y++;
}
} else if(dir == 'up') {
if(x-1 <= i-1) {
dir = 'left';
y--;
} else {
x--;
}
} else if(dir == 'left') {
y--;
}
index++;
}
}
matrix.map(row => console.log(row.join(' ')));
}
const matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
// rotate count
const r = 3
matrixRotation(matrix, r);
答案 1 :(得分:0)
此方法应支持matrix
和matrix[n]
的任何大小。如果适合您,请尝试使用各种测试用例。
请注意,这里我忽略了任何性能缺陷。
var arr = [
[ 1, 2, 3, 4 ],
[ 5, 6, 7, 8 ],
[ 9, 10, 11, 12 ],
[ 13, 14, 15, 16 ]
],
result = [];
while ( arr.flat().length ) {
var res = [];
// 1. Left side
arr.forEach(x => res = res.concat( x.splice(0, 1) ));
// 2. Bottom side
if (arr.length) {
res = res.concat( ...arr.splice(arr.length - 1, 1) );
}
// 3. Right side
var tmp = [];
if (arr.flat().length) {
arr.forEach(x => tmp.push( x.splice(arr.length - 1, 1) ));
res = res.concat( ...tmp.reverse() );
}
// 4. Top side
if (arr.length) {
tmp = [].concat( ...arr.splice(0, 1) );
res = res.concat( tmp.reverse() );
}
result.push(res);
}
console.log(result);
答案 2 :(得分:0)
我将以分层的方式编写此代码,编写矩阵转置逻辑(即在西北偏南对角线上翻转矩阵),并使用该代码和简单的reverse
来建立矩阵的逆时针旋转矩阵,使用该旋转来建立顺时针螺旋,最后再次在顺时针螺旋旁边使用transpose
来建立逆时针螺旋。
我之所以选择此顺序,是因为通常更需要顺时针螺旋,但是直接构建逆时针螺旋将很容易。 提示:rotateClockwise = m => transpose(reverse(m))
。
const reverse = a => [...a].reverse();
const transpose = m => m[0].map((c, i) => m.map(r => r[i]))
const rotateCounter = m => reverse(transpose(m))
const spiralClockwise = m => m.length < 2
? m[0]
: m[0].concat(spiralClockwise(rotateCounter(m.slice(1))))
const spiralCounter = m => spiralClockwise(transpose(m))
console.log(spiralCounter([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]))
请注意,这里的中间函数本身很有可能有用。因此,这是解决该问题的好方法。
答案 3 :(得分:0)
给出数组:
array =
[
[ '00', '01', '02', '03', '04', '05'],
[ '10', '11', '12', '13', '14', '15'],
[ '20', '21', '22', '23', '24', '25'],
[ '30', '31', '32', '33', '34', '35']
]
这将返回外部循环:
external_ccw_round = [array.map(&:shift), array.pop, array.map(&:pop).reverse, array.shift.reverse].flatten
#=> ["00", "10", "20", "30", "31", "32", "33", "34", "35", "25", "15", "05", "04", "03", "02", "01"]
只留下核心
array #=> [["11", "12", "13", "14"], ["21", "22", "23", "24"]]
对于多于一行的矩阵。
这是一种具有递归实现的方法
适用于任何二维矩阵。
def ccw_scan(array, result=[])
return array if array.size <= 1
result << [array.map(&:shift), array.pop, array.map(&:pop).reverse, array.shift.reverse]
if array.size >= 2
then ccw_scan(array, result)
else result << array
end
result.flatten.compact
end
在数组上调用方法:
ccw_scan(array)
#=> ["00", "10", "20", "30", "31", "32", "33", "34", "35", "25", "15", "05", "04", "03", "02", "01", "11", "21", "22", "23", "24", "14", "13", "12"]
答案 4 :(得分:0)
这就是我用红宝石处理的方式:
def counter_clockwise!(arr)
return arr if arr.size <= 1
rotation = [
arr.map(&:shift)
.concat(arr.pop,
arr.map(&:pop).reverse,
arr.shift.reverse).compact
]
rotation.push(*send(__method__,arr)) unless arr.all?(&:empty?)
rotation
end
def counter_clockwise(arr)
counter_clockwise!(arr.map(&:dup))
end
示例:
arr = [
[ 1, 2, 3, 4 ],
[ 5, 6, 7, 8 ],
[ 9, 10, 11, 12 ],
[ 13, 14, 15, 16 ],
[ 17, 18, 19, 20 ],
[ 21, 22, 23, 24 ]
]
counter_clockwise(arr)
#=> [[1, 5, 9, 13, 17, 21, 22, 23, 24, 20, 16, 12, 8, 4, 2, 3],
# [6, 10, 14, 18, 19, 15, 11, 7]]
此方法将外部边缘递归处理为组(原始帖子中的“循环”)。显然,如果只希望没有组的逆时针螺旋,则可以使返回值变平。
这还将处理非M x N个矩阵,例如:
arr = [
[ 1, 2, 3, 4 , 72 ],
[ 5, 6, 7, 8 , 73 ],
[ 9, 10, 11 , 12 ],
[ 13, 14, 16 , 75 ],
[ 17, 18, 19, 20 , 76 ],
[ 21, 22, 23, 24 , 77 ]
]
counter_clockwise(arr)
#=> [[1, 5, 9, 13, 17, 21, 22, 23, 24, 77, 76, 75, 12, 73, 72, 4, 3, 2],
# [6, 10, 14, 18, 19, 20, 16, 11, 8, 7]]
如果您希望每个边缘都可以保证M x N,那么这也将起作用
def counter_clockwise_edges(arr)
return arr if arr.size == 1
arr = arr.transpose
[arr.shift].push(*send(__method__,arr.map(&:reverse)))
end
counter_clockwise_edges(arr)
#=> [[1, 5, 9, 13, 17, 21],
[22, 23, 24],
[20, 16, 12, 8, 4],
[3, 2],
[6, 10, 14, 18],
[19, 15, 11, 7]]
答案 5 :(得分:0)
以下是我对this SO question的回答的一种修改,与之不同之处仅在于数组沿相反的方向遍历。
arr = matrix.map(&:dup).transpose
#=> [[1, 5, 9, 13], [2, 6, 10, 14], [3, 7, 11, 15], [4, 8, 12, 16]]
步骤如下。
matrix
我对out = []
out = out + arr.shift
#=> [1, 5, 9, 13]
arr
#=> [[2, 6, 10, 14], [3, 7, 11, 15], [4, 8, 12, 16]]
arr = arr.transpose.reverse
#=> [[14, 15, 16], [10, 11, 12], [6, 7, 8], [2, 3, 4]]
out = out + arr.shift
#=> [1, 5, 9, 13, 14, 15, 16]
arr
#=> [[10, 11, 12], [6, 7, 8], [2, 3, 4]]
arr = arr.transpose.reverse
#=> [[12, 8, 4], [11, 7, 3], [10, 6, 2]]
out = out + arr.shift
#=> [1, 5, 9, 13, 14, 15, 16, 12, 8, 4]
arr
#=> [[11, 7, 3], [10, 6, 2]]
arr = arr.transpose.reverse
#=> [[3, 2], [7, 6], [11, 10]]
out = out + arr.shift
#=> [1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2]
arr
#=> [[7, 6], [11, 10]]
的元素进行了欺骗,以使后者不会被突变。
arr = arr.transpose.reverse
#=> [[6, 10], [7, 11]]
out = out + arr.shift
#=> [1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10]
arr
#=> [[7, 11]]
arr = arr.transpose.reverse
#=> [[11], [7]]
out = out + arr.shift
#=> [1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10, 11]
arr
#=> [[7]]
arr = arr.transpose.reverse
#=> [[7]]
out = out + arr.shift
#=> [1, 5, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10, 11, 7]
arr
#=> []
arr
由于break
现在为空,我们out
返回arr
arr = arr.transpose.reverse
out = out + arr.shift
arr
arr = arr.transpose.reverse
out = out + arr.shift
arr
arr = arr.transpose.reverse
out = out + arr.shift
arr
arr = arr.transpose.reverse
out = out + arr.shift
arr
arr = arr.transpose.reverse
out = out + arr.shift
arr
arr = arr.transpose.reverse
。
from tkinter import*
import tkinter as tk
class QueueApp(tk.Tk):
def __init__(self):
super().__init__()
self.title(' Queue')
self.minsize(200, 200)
self.x=0
self.frame1=tk.Frame(self)
self.frame1.place(x=0,y=0,width=70,height=170,anchor='nw')
self.frame2=tk.Frame(self)
self.frame2.place(x=40,y=175,anchor='nw')
self.frame3 = tk.Frame(self)
self.frame3.place(x=100, y=0, width=50, height=170, anchor='nw')
add=tk.Button(self.frame2,text='add',command=self.add_text)
add.pack()
def add_text(self):
self.x=self.x+1
self.text=tk.Label(self.frame1,text=self.x)
self.text.pack(side=tk.TOP)
self.delete_button=tk.Button(self.frame3,text='delete',
command=self.delete)
self.delete_button.pack(side=tk.TOP)
def delete(self):
self.text.destroy()
self.delete_button.destroy()
if __name__=='__main__':
app = QueueApp()
app.mainloop()