আপনি কীভাবে একটি দ্বিমাত্রিক অ্যারে ঘোরান?


302

রেমন্ড চেনের পোস্ট থেকে অনুপ্রাণিত হয়ে বলুন আপনার কাছে 4x4 দ্বিমাত্রিক অ্যারে রয়েছে, এমন একটি ফাংশন লিখুন যা এটি 90 ডিগ্রি ঘোরায়। রেমন্ড সিউডো কোডে একটি সমাধানের সাথে লিঙ্ক করে তবে আমি কিছু বাস্তব বিশ্বের জিনিস দেখতে চাই।

[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]

হয়ে:

[3][9][5][1]
[4][0][6][2]
[5][1][7][3]
[6][2][8][4]

আপডেট : নিকের উত্তর সর্বাধিক সোজাসাপ্টা, তবে n ^ 2 এর চেয়ে ভাল করার কোনও উপায় আছে কি? ম্যাট্রিক্স 10000x10000 হলে কী হত?


99
আপনি কীভাবে n ^ 2 এর চেয়ে কম দিয়ে পালাতে পারবেন? সমস্ত উপাদানগুলি অবশ্যই পড়তে হবে এবং সেট করতে হবে, এবং সেখানে n ^ 2 উপাদান রয়েছে
এরিক্কাল্লেন


9
আপনার এন কি? আপনি যদি বলেন না যে 2 ডি অ্যারেটি বর্গক্ষেত্র হয় (এটি সাধারণ ক্ষেত্রে হয় না! উদাহরণস্বরূপ ভেক্টরটি 1 এর একটি মাত্রা সহ একটি ম্যাট্রিক্স), তবুও আপনি বোঝাচ্ছেন যে n প্রস্থ এবং উচ্চতা, এবং সুতরাং উপাদানগুলি নেই । N = w × h এর সাহায্যে উপাদানগুলির সংখ্যা n হওয়া আরও বোধগম্য হবে।
নিক্সর

1
এটি করার একটি দ্রুত উপায় এখানে রয়েছে: সারি এবং কলাম সূচকগুলি সংরক্ষণ করুন (বলুন আমি এবং জে)। ট্রান্সপোজ করতে স্থির সময় লাগে (কেবল সূচকগুলিকে অদলবদল করুন :))। আপনি একই ঘূর্ণন (সূচকের সাথে খেলতে) করতে পারেন।
সাদাতাম

4
যদি n ^ 2 সম্ভব হয় না। আপনি একটি ইন্টারফেস তৈরি করতে পারেন যা প্রতিটি উপাদান অ্যাক্সেস করে। তারপরে (i, j) প্রদত্ত, ঘোরানো উপাদানটি অ্যাক্সেস করে (i, j) এ ঘূর্ণন প্রয়োগ করুন এবং ফিরে আসুন। সেরা সলান না হয়ে কাজ করতে পারে।
গুলান

উত্তর:


140

এখানে এটি সি # তে রয়েছে

int[,] array = new int[4,4] {
    { 1,2,3,4 },
    { 5,6,7,8 },
    { 9,0,1,2 },
    { 3,4,5,6 }
};

int[,] rotated = RotateMatrix(array, 4);

static int[,] RotateMatrix(int[,] matrix, int n) {
    int[,] ret = new int[n, n];

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            ret[i, j] = matrix[n - j - 1, i];
        }
    }

    return ret;
}

6
অবশ্যই, তবে ও (1) মেমরি ব্যবহার করে কোনও সমাধান সম্পর্কে কী?
অ্যালেক্সিএমকে

20
আপনার সমাধানে O (n ^ 2) স্পেস জটিলতা রয়েছে। আরও ভাল করার দরকার
ক্ষিতিজ জৈন

6
এনএক্সএম ম্যাট্রিক্স সম্পর্কে কীভাবে?
রোহিত

17
অ্যারেতে উপাদানের সংখ্যায় জটিলতা রৈখিক। যদি N হ'ল উপাদানগুলির সংখ্যা হয় তবে জটিলতা হ'ল O (N)। N যদি পাশের দৈর্ঘ্য হয় তবে হ্যাঁ, জটিলতাটি O (N ^ 2), তবে এটি এখনও অনুকূল। আপনাকে প্রতিটি উপাদান কমপক্ষে একবারে পড়তে হবে। ম্যাট্রিক্স মুদ্রণ একই জটিলতা
আলেজান্দ্রো

6
একটি -৯০ ডিগ্রি ঘোরার জন্য:ret[i][j] = matrix[j][n - i - 1]
ডানকান লুক

387

ও (এন ^ 2) সময় এবং হে (1) স্পেস অ্যালগরিদম (কোনও কাজের ক্ষেত্র এবং হ্যাঙ্কি-প্যাঙ্কি স্টাফ ছাড়াই!)

+90 দ্বারা ঘোরান:

  1. পক্ষান্তরিত করা
  2. প্রতিটি সারি বিপরীত

-৯০-এ ঘোরান:

পদ্ধতি 1:

  1. পক্ষান্তরিত করা
  2. প্রতিটি কলাম বিপরীত

পদ্ধতি 2:

  1. প্রতিটি সারি বিপরীত
  2. পক্ষান্তরিত করা

+180 দ্বারা ঘোরান:

পদ্ধতি 1 : দুবার +90 দ্বারা ঘোরান

পদ্ধতি 2 : প্রতিটি সারি বিপরীত করুন এবং তারপরে প্রতিটি কলাম বিপরীত করুন (ট্রান্সপোজ)

-180 দ্বারা ঘোরান:

পদ্ধতি 1 : দুবার -90 দ্বারা ঘোরান

পদ্ধতি 2 : প্রতিটি কলাম বিপরীত করুন এবং তারপরে প্রতিটি সারি বিপরীত করুন

পদ্ধতি 3 : +180 একই হয় এমনভাবে ঘোরান


4
এটি আমার জন্য খুব সহায়ক ছিল; এই ক্রিয়াকলাপটির "[ছদ্ম-] কোড সংস্করণ" জানার পরে আমি একটি অ্যালগরিদম লিখতে সক্ষম হয়েছি। ধন্যবাদ!
ডুমা

13
আমার সর্বকালের প্রিয় এসও উত্তরগুলির মধ্যে একটি। খুব শিক্ষামূলক!
g33kz0r

2
যদি কেউ আগ্রহী হন তবে এখানে একটি জাভাস্ক্রিপ্ট বাস্তবায়ন জেএসফিডাল
মিঃ পলিহর্ল

6
-৯০ দ্বারা ঘোরান: (1) প্রতিটি সারি বিপরীত; (2) ট্রান্সপোজ। হাস্কেল: rotateCW = map reverse . transposeএবংrotateCCW = transpose . map reverse
থমাস এডিং

5
180 এবং -180 ঘোরার মধ্যে পার্থক্য কী?
কিয়ান চেন

177

আমি আরও কিছু বিশদ যুক্ত করতে চাই। এই উত্তরে, মূল ধারণাগুলি পুনরাবৃত্তি হয়, গতি ধীর এবং ইচ্ছাকৃতভাবে পুনরাবৃত্তি হয়। এখানে প্রদত্ত সমাধানটি সর্বাধিক সিনট্যাক্টিক্যালি কমপ্যাক্ট নয়, তবে এটি তাদের জন্য যারা ম্যাট্রিক্স ঘূর্ণন কী এবং ফলাফলটি বাস্তবায়ন কী তা শিখতে চান implementation

প্রথমত, একটি ম্যাট্রিক্স কি? এই উত্তরের উদ্দেশ্যে, একটি ম্যাট্রিক্স কেবল একটি গ্রিড যেখানে প্রস্থ এবং উচ্চতা একই the দ্রষ্টব্য, ম্যাট্রিক্সের প্রস্থ এবং উচ্চতা আলাদা হতে পারে তবে সরলতার জন্য এই টিউটোরিয়ালটি সমান প্রস্থ এবং উচ্চতা সহ কেবল ম্যাট্রিককে বিবেচনা করে ( বর্গ ম্যাট্রিক্স ) । এবং হ্যাঁ, ম্যাট্রিক্স হ'ল ম্যাট্রিক্সের বহুবচন।

উদাহরণ ম্যাট্রিকগুলি হ'ল: 2 × 2, 3 × 3 বা 5 × 5। অথবা, আরও সাধারণভাবে, N × N। একটি 2 × 2 ম্যাট্রিক্সের 4 স্কোয়ার থাকবে কারণ 2 × 2 = 4। একটি 5 × 5 ম্যাট্রিক্সের 25 স্কোয়ার থাকবে কারণ 5 × 5 = 25। প্রতিটি বর্গকে একটি উপাদান বা এন্ট্রি বলা হয়। আমরা .নীচের চিত্রগুলিতে একটি পিরিয়ড ( ) সহ প্রতিটি উপাদানকে উপস্থাপন করব :

2 × 2 ম্যাট্রিক্স

. .
. .

3 × 3 ম্যাট্রিক্স

. . .
. . .
. . .

4 × 4 ম্যাট্রিক্স

. . . .
. . . .
. . . .
. . . .

সুতরাং, ম্যাট্রিক্সকে ঘোরানোর অর্থ কী? আসুন একটি 2 × 2 ম্যাট্রিক্স নিন এবং প্রতিটি উপাদানগুলিতে কিছু নম্বর রাখুন যাতে ঘূর্ণনটি লক্ষ করা যায়:

0 1
2 3

এটি 90 ডিগ্রি ঘোরানো আমাদের দেয়:

2 0
3 1

আমরা গাড়ীর স্টিয়ারিং হুইল ঘুরিয়ে দেওয়ার মতো করে আক্ষরিকভাবে পুরো ম্যাট্রিক্সটি একবার ডানদিকে পরিণত করেছিলাম। এটি ম্যাট্রিক্সকে তার ডানদিকে "টিপ" দেওয়ার কথা ভাবতে সহায়তা করতে পারে। পাইথনে আমরা একটি ফাংশন লিখতে চাই, এটি একটি ম্যাট্রিক্স নেয় এবং একবার ডানে ঘুরবে। ফাংশনের স্বাক্ষরটি হবেন:

def rotate(matrix):
    # Algorithm goes here.

ম্যাট্রিক্স দ্বি-মাত্রিক অ্যারে ব্যবহার করে সংজ্ঞায়িত করা হবে:

matrix = [
    [0,1],
    [2,3]
]

সুতরাং প্রথম সূচীর অবস্থানটি সারিটি অ্যাক্সেস করে। দ্বিতীয় সূচক অবস্থানটি কলামটি অ্যাক্সেস করে:

matrix[row][column]

আমরা ম্যাট্রিক্স মুদ্রণের জন্য একটি ইউটিলিটি ফাংশনটি সংজ্ঞায়িত করব।

def print_matrix(matrix):
    for row in matrix:
        print row

ম্যাট্রিক্স ঘোরানোর একটি পদ্ধতি হ'ল এটি একবারে একটি স্তর করা। কিন্তু একটি স্তর কি? একটি পেঁয়াজ ভাবেন। পেঁয়াজের স্তরগুলি যেমন প্রতিটি স্তর সরানো হয় তেমনি আমরা কেন্দ্রের দিকে এগিয়ে যাই move অন্যান্য উপমা হ'ল ক ম্যাট্রিওস্কা পুতুল বা পাস-দ্য পার্সেলের একটি খেলা।

একটি ম্যাট্রিক্সের প্রস্থ এবং উচ্চতা সেই ম্যাট্রিক্সের স্তরগুলির সংখ্যা নির্ধারণ করে। প্রতিটি স্তরের জন্য পৃথক চিহ্ন ব্যবহার করা যাক:

একটি 2 × 2 ম্যাট্রিক্সের 1 স্তর রয়েছে

. .
. .

একটি 3 × 3 ম্যাট্রিক্সের 2 স্তর রয়েছে

. . .
. x .
. . .

একটি 4 × 4 ম্যাট্রিক্সের 2 স্তর রয়েছে

. . . .
. x x .
. x x .
. . . .

একটি 5 × 5 ম্যাট্রিক্সে 3 স্তর রয়েছে

. . . . .
. x x x .
. x O x .
. x x x .
. . . . .

একটি 6 × 6 ম্যাট্রিক্সে 3 স্তর রয়েছে

. . . . . .
. x x x x .
. x O O x .
. x O O x .
. x x x x .
. . . . . .

একটি 7 × 7 ম্যাট্রিক্সে 4 স্তর রয়েছে

. . . . . . .
. x x x x x .
. x O O O x .
. x O - O x .
. x O O O x .
. x x x x x .
. . . . . . .

আপনি লক্ষ করতে পারেন যে ম্যাট্রিক্সের প্রস্থ এবং উচ্চতা এক এক করে বৃদ্ধি করা সর্বদা স্তরগুলির সংখ্যা বৃদ্ধি করে না। উপরের ম্যাট্রিকগুলি গ্রহণ করা এবং স্তরগুলি এবং মাত্রাগুলিগুলিকে টেবুলেট করা, আমরা দেখতে পাচ্ছি প্রস্থ এবং উচ্চতার প্রতি দুটি বর্ধনের জন্য একবার স্তরগুলির সংখ্যা বৃদ্ধি পায়:

+-----+--------+
| N×N | Layers |
+-----+--------+
| 1×1 |      1 |
| 2×2 |      1 |
| 3×3 |      2 |
| 4×4 |      2 |
| 5×5 |      3 |
| 6×6 |      3 |
| 7×7 |      4 |
+-----+--------+

তবে, সমস্ত স্তর ঘোরানোর প্রয়োজন হয় না। আবর্তনের আগে এবং পরে একটি 1 × 1 ম্যাট্রিক্স একই। কেন্দ্রের 1 × 1 স্তরটি সার্বক্ষণিক ঘূর্ণনের আগে এবং পরে সর্বদা একই রকম হয়, সামগ্রিক ম্যাট্রিক্স যত বড়ই নয়:

+-----+--------+------------------+
| N×N | Layers | Rotatable Layers |
+-----+--------+------------------+
| 1×1 |      1 |                0 |
| 2×2 |      1 |                1 |
| 3×3 |      2 |                1 |
| 4×4 |      2 |                2 |
| 5×5 |      3 |                2 |
| 6×6 |      3 |                3 |
| 7×7 |      4 |                3 |
+-----+--------+------------------+

এন mat এন ম্যাট্রিক্স দেওয়া, আমরা কীভাবে স্তর ঘোরানোর জন্য প্রয়োজনীয় স্তরগুলি প্রোগ্রামের মাধ্যমে নির্ধারণ করতে পারি? আমরা যদি প্রস্থ বা উচ্চতাটিকে দুটি দ্বারা বিভক্ত করি এবং বাকী অংশটিকে উপেক্ষা করি আমরা নিম্নলিখিত ফলাফলগুলি পাই।

+-----+--------+------------------+---------+
| N×N | Layers | Rotatable Layers |   N/2   |
+-----+--------+------------------+---------+
| 1×1 |      1 |                0 | 1/2 = 0 |
| 2×2 |      1 |                1 | 2/2 = 1 |
| 3×3 |      2 |                1 | 3/2 = 1 |
| 4×4 |      2 |                2 | 4/2 = 2 |
| 5×5 |      3 |                2 | 5/2 = 2 |
| 6×6 |      3 |                3 | 6/2 = 3 |
| 7×7 |      4 |                3 | 7/2 = 3 |
+-----+--------+------------------+---------+

কিভাবে লক্ষ করুন N/2 স্তরগুলি ঘোরানো দরকার তার সংখ্যার সাথে মেলে? কখনও কখনও ঘূর্ণনযোগ্য স্তরগুলির সংখ্যা ম্যাট্রিক্সের মোট স্তরগুলির চেয়ে কম হয়। এটি ঘটে যখন অন্তঃস্থল স্তরটি কেবলমাত্র একটি উপাদান (যেমন একটি 1 × 1 ম্যাট্রিক্স) নিয়ে গঠিত হয় এবং তাই ঘোরানোর প্রয়োজন হয় না। এটি কেবল উপেক্ষা করা হয়।

নিঃসন্দেহে একটি ম্যাট্রিক্স ঘোরানোর জন্য আমাদের ফাংশনটিতে এই তথ্যটির প্রয়োজন হবে, তাই এখনই এটি যুক্ত করুন:

def rotate(matrix):
    size = len(matrix)
    # Rotatable layers only.
    layer_count = size / 2

এখন আমরা জানি স্তরগুলি কী এবং কীভাবে স্তরগুলি ঘোরানোর প্রয়োজন তা নির্ধারণ করতে, আমরা কীভাবে একটি স্তরকে আলাদা করব যাতে আমরা এটি ঘোরান? প্রথমত, আমরা বাইরেরতম স্তর থেকে অভ্যন্তরীণতম স্তর পর্যন্ত একটি ম্যাট্রিক্স পরিদর্শন করি। একটি 5 × 5 ম্যাট্রিক্সে মোট তিনটি স্তর রয়েছে এবং দুটি স্তর রয়েছে যা ঘোরানোর প্রয়োজন:

. . . . .
. x x x .
. x O x .
. x x x .
. . . . .

প্রথমে কলামগুলি দেখুন। বাহ্যতম স্তরকে সংজ্ঞায়িত করে কলামগুলির অবস্থান, ধরে নেওয়া আমরা 0 থেকে গণনা করছি, 0 এবং 4:

+--------+-----------+
| Column | 0 1 2 3 4 |
+--------+-----------+
|        | . . . . . |
|        | . x x x . |
|        | . x O x . |
|        | . x x x . |
|        | . . . . . |
+--------+-----------+

0 এবং 4 হ'ল বহিরাগত স্তরের সারিগুলির অবস্থানও।

+-----+-----------+
| Row |           |
+-----+-----------+
|   0 | . . . . . |
|   1 | . x x x . |
|   2 | . x O x . |
|   3 | . x x x . |
|   4 | . . . . . |
+-----+-----------+

প্রস্থ এবং উচ্চতা সমান হওয়ায় এটি সর্বদা ক্ষেত্রে হবে। সুতরাং আমরা মাত্র দুটি মান (চারটি নয়) দিয়ে একটি স্তরের কলাম এবং সারি অবস্থান নির্ধারণ করতে পারি।

দ্বিতীয় স্তরের দিকে অগ্রসর হওয়া, কলামগুলির অবস্থান 1 এবং 3 And এবং হ্যাঁ, আপনি এটি অনুমান করেছিলেন, এটি সারিগুলির জন্য একই। পরবর্তী স্তরের দিকে যাওয়ার সময় আমাদের সারি এবং কলামের অবস্থান বৃদ্ধি এবং হ্রাস উভয়ই ছিল তা বোঝা গুরুত্বপূর্ণ।

+-----------+---------+---------+---------+
|   Layer   |  Rows   | Columns | Rotate? |
+-----------+---------+---------+---------+
| Outermost | 0 and 4 | 0 and 4 | Yes     |
| Inner     | 1 and 3 | 1 and 3 | Yes     |
| Innermost | 2       | 2       | No      |
+-----------+---------+---------+---------+

সুতরাং, প্রতিটি স্তরটি পরিদর্শন করতে, আমরা উভয় বাড়ানো এবং হ্রাসকারী কাউন্টারগুলির সাথে একটি লুপ চাই যা বাহিরের স্তর থেকে শুরু করে ভেতরের দিকে অগ্রসর হওয়া প্রতিনিধিত্ব করে। আমরা এটিকে আমাদের 'স্তর লুপ' বলব।

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2

    for layer in range(0, layer_count):
        first = layer
        last = size - first - 1
        print 'Layer %d: first: %d, last: %d' % (layer, first, last)

# 5x5 matrix
matrix = [
    [ 0, 1, 2, 3, 4],
    [ 5, 6, 6, 8, 9],
    [10,11,12,13,14],
    [15,16,17,18,19],
    [20,21,22,23,24]
]

rotate(matrix)

ঘোরানো দরকার এমন কোনও স্তরগুলির (সারি এবং কলাম) অবস্থানের উপরের কোডটি লুপ করে।

Layer 0: first: 0, last: 4
Layer 1: first: 1, last: 3

আমাদের কাছে এখন প্রতিটি স্তরের সারি এবং কলামের অবস্থান সরবরাহকারী একটি লুপ রয়েছে। ভেরিয়েবলগুলি firstএবং lastপ্রথম এবং শেষ সারি এবং কলামগুলির সূচী অবস্থান সনাক্ত করে। আমাদের সারি এবং কলামের সারণীতে ফিরে উল্লেখ:

+--------+-----------+
| Column | 0 1 2 3 4 |
+--------+-----------+
|        | . . . . . |
|        | . x x x . |
|        | . x O x . |
|        | . x x x . |
|        | . . . . . |
+--------+-----------+

+-----+-----------+
| Row |           |
+-----+-----------+
|   0 | . . . . . |
|   1 | . x x x . |
|   2 | . x O x . |
|   3 | . x x x . |
|   4 | . . . . . |
+-----+-----------+

সুতরাং আমরা একটি ম্যাট্রিক্স এর স্তর মাধ্যমে নেভিগেট করতে পারেন। এখন আমাদের একটি স্তরের মধ্যে নেভিগেট করার একটি উপায় প্রয়োজন যাতে আমরা সেই স্তরটির চারপাশে উপাদানগুলি স্থানান্তর করতে পারি। দ্রষ্টব্য, উপাদানগুলি কখনই এক স্তর থেকে অন্য স্তরটিতে 'লাফায়' না, তবে তারা তাদের নিজ স্তরের মধ্যে চলে move

প্রতিটি উপাদানকে একটি স্তরে ঘোরানো পুরো স্তরটি ঘোরায়। ম্যাট্রিক্সে সমস্ত স্তর ঘোরানো পুরো ম্যাট্রিক্সকে ঘোরায়। এই বাক্যটি অত্যন্ত গুরুত্বপূর্ণ, সুতরাং এগিয়ে যাওয়ার আগে দয়া করে এটি বোঝার জন্য যথাসাধ্য চেষ্টা করুন।

এখন, আমাদের আসলে চলমান উপাদানগুলির একটি উপায় প্রয়োজন, অর্থাত প্রতিটি উপাদান ঘোরানো, এবং পরবর্তীকালে স্তর এবং শেষ পর্যন্ত ম্যাট্রিক্স। সরলতার জন্য, আমরা একটি 3x3 ম্যাট্রিক্সে ফিরব - যার একটি ঘূর্ণনযোগ্য স্তর রয়েছে।

0 1 2
3 4 5
6 7 8

আমাদের স্তর লুপটি প্রথম এবং শেষ কলামগুলির সূচি পাশাপাশি প্রথম এবং শেষ সারিগুলি সরবরাহ করে:

+-----+-------+
| Col | 0 1 2 |
+-----+-------+
|     | 0 1 2 |
|     | 3 4 5 |
|     | 6 7 8 |
+-----+-------+

+-----+-------+
| Row |       |
+-----+-------+
|   0 | 0 1 2 |
|   1 | 3 4 5 |
|   2 | 6 7 8 |
+-----+-------+

আমাদের ম্যাট্রিক্স সবসময় বর্গ কারণ, আমরা শুধু দুটি ভেরিয়েবল প্রয়োজন, firstএবং lastযেহেতু সূচক অবস্থানের সারি এবং কলামের জন্য একই।

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2

    # Our layer loop i=0, i=1, i=2
    for layer in range(0, layer_count):

        first = layer
        last = size - first - 1

        # We want to move within a layer here.

প্রথম এবং শেষের ভেরিয়েবলগুলি ম্যাট্রিক্সের চারটি কোণগুলির জন্য সহজেই ব্যবহার করা যেতে পারে। এটি কারণ কোণগুলি তাদের নিজস্ব বিবিধ ক্রম ব্যবহার করে সংজ্ঞায়িত করা যেতে পারে firstএবং last(সেই পরিবর্তনকের কোনও বিয়োগ, যোগ বা অফসেট ছাড়াই):

+---------------+-------------------+-------------+
| Corner        | Position          | 3x3 Values  |
+---------------+-------------------+-------------+
| top left      | (first, first)    | (0,0)       |
| top right     | (first, last)     | (0,2)       |
| bottom right  | (last, last)      | (2,2)       |
| bottom left   | (last, first)     | (2,0)       |
+---------------+-------------------+-------------+

এই কারণে, আমরা আমাদের ঘূর্ণনটি বাইরের চার কোণে শুরু করি - আমরা প্রথমে সেগুলি ঘোরাব। এর সাথে তাদের হাইলাইট করা যাক *

* 1 *
3 4 5
* 7 *

আমরা একে অদলবদল করতে চান *সঙ্গে *এটা ডানদিকে। সুতরাং আসুন একটি প্রিন্ট আউট করা আমাদের কোণগুলি কেবলমাত্র বিভিন্ন ক্রিয়াকলাপগুলি firstএবং এর ব্যবহার করে সংজ্ঞায়িত করা যেতে পারে last:

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2
    for layer in range(0, layer_count):

        first = layer
        last = size - first - 1

        top_left = (first, first)
        top_right = (first, last)
        bottom_right = (last, last)
        bottom_left = (last, first)

        print 'top_left: %s' % (top_left)
        print 'top_right: %s' % (top_right)
        print 'bottom_right: %s' % (bottom_right)
        print 'bottom_left: %s' % (bottom_left)

matrix = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
]

rotate(matrix)

আউটপুট হওয়া উচিত:

top_left: (0, 0)
top_right: (0, 2)
bottom_right: (2, 2)
bottom_left: (2, 0)

এখন আমরা আমাদের লেয়ার লুপের মধ্যে থেকে প্রতিটি কোণকে খুব সহজেই অদলবদল করতে পারি:

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2
    for layer in range(0, layer_count):

        first = layer
        last = size - first - 1

        top_left = matrix[first][first]
        top_right = matrix[first][last]
        bottom_right = matrix[last][last]
        bottom_left = matrix[last][first]

        # bottom_left -> top_left
        matrix[first][first] = bottom_left
        # top_left -> top_right
        matrix[first][last] = top_left
        # top_right -> bottom_right
        matrix[last][last] = top_right
        # bottom_right -> bottom_left
        matrix[last][first] = bottom_right


print_matrix(matrix)
print '---------'
rotate(matrix)
print_matrix(matrix)

কোণ ঘোরার আগে ম্যাট্রিক্স:

[0, 1, 2]
[3, 4, 5]
[6, 7, 8]

কোণ ঘোরার পরে ম্যাট্রিক্স:

[6, 1, 0]
[3, 4, 5]
[8, 7, 2]

গ্রেট! আমরা ম্যাট্রিক্সের প্রতিটি কোণকে সাফল্যের সাথে ঘোরালাম। তবে, আমরা প্রতিটি স্তরের মাঝখানে উপাদানগুলি ঘোরানো হয়নি। স্পষ্টতই আমাদের একটি স্তর মধ্যে পুনরাবৃত্তি একটি উপায় প্রয়োজন।

সমস্যাটি হল, আমাদের ফাংশনটিতে এখন পর্যন্ত একমাত্র লুপ (আমাদের স্তর লুপ) প্রতিটি পুনরাবৃত্তির পরবর্তী স্তরটিতে চলে আসে। যেহেতু আমাদের ম্যাট্রিক্সের কেবল একটি ঘূর্ণনযোগ্য স্তর রয়েছে তাই স্তর কোণটি কেবল কোণগুলি ঘোরার পরে প্রস্থান করে। আসুন দেখে নেওয়া যাক বৃহত্তর, 5 × 5 ম্যাট্রিক্সের সাথে কী ঘটে (যেখানে দুটি স্তর ঘোরানো দরকার)। ফাংশন কোড বাদ দেওয়া হয়েছে, তবে এটি উপরের মতোই রয়েছে:

matrix = [
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]
]
print_matrix(matrix)
print '--------------------'
rotate(matrix)
print_matrix(matrix)

আউটপুটটি হ'ল:

[20,  1,  2,  3,  0]
[ 5, 16,  7,  6,  9]
[10, 11, 12, 13, 14]
[15, 18, 17,  8, 19]
[24, 21, 22, 23,  4]

আশ্চর্য হওয়া উচিত নয় যে বাইরেরতম স্তরটির কোণগুলি ঘোরানো হয়েছে, তবে, আপনি পরবর্তী স্তরটির (কোণার) কোণগুলিও ঘোরানো হয়েছে তা লক্ষ্য করতে পারেন। এইবার বুঝতে পারছি. আমরা স্তরগুলির মাধ্যমে নেভিগেট করার জন্য এবং প্রতিটি স্তরের কোণগুলিকে ঘোরানোর জন্য কোড লিখেছি। এটি অগ্রগতির মতো অনুভব করে তবে দুর্ভাগ্যক্রমে আমাদের অবশ্যই এক পদক্ষেপ নিতে হবে। পূর্ববর্তী (বাহ্যিক) স্তরটি পুরোপুরি ঘোরানো না হওয়া পর্যন্ত এটি পরবর্তী স্তরটির দিকে চলে যাওয়ার খুব ভাল নয়। অর্থাৎ স্তরের প্রতিটি উপাদান ঘোরানো না হওয়া পর্যন্ত। কেবল কোণগুলি ঘোরানো হবে না!

একটা গভীর শ্বাস নাও. আমাদের আরেকটি লুপ দরকার। নেস্টেড লুপটি আর কম নয়। নতুন, নেস্টেড লুপটি একটি স্তরটির মধ্যে নেভিগেট করার জন্য firstএবং lastভেরিয়েবলগুলি, এবং একটি অফসেট ব্যবহার করবে । আমরা এই নতুন লুপটিকে আমাদের 'এলিমেন্ট লুপ' বলব। এলিমেন্ট লুপটি প্রতিটি সারিটি উপরের সারিতে বরাবর, প্রতিটি উপাদানকে ডান পাশের নীচে, প্রতিটি উপাদান নীচের সারি বরাবর এবং প্রতিটি উপাদান বাম দিকে উপস্থাপন করবে।

  • শীর্ষ সারিতে অগ্রসর হওয়ার জন্য কলাম সূচকটি বাড়ানো দরকার।
  • ডানদিকে নিচে চলতে সারি সূচকটি বাড়ানো দরকার।
  • নীচে বরাবর পিছনে সরে যাওয়ার জন্য কলাম সূচি হ্রাস করতে হবে।
  • বাম দিকে উপরে উঠতে সারি সূচকে হ্রাস করতে হবে।

এটি জটিল মনে হচ্ছে, তবে এটি সহজ হয়েছে কারণ উপরেরটি অর্জনের জন্য আমরা যত বার বৃদ্ধি পেয়েছি এবং হ্রাস পেয়েছি তার সংখ্যা ম্যাট্রিক্সের চারটি পাশেই একই রয়েছে। উদাহরণ স্বরূপ:

  • উপরের সারিতে 1 টি উপাদান সরান।
  • 1 এলিমেন্টটি ডান দিক থেকে সরান।
  • নীচের সারি বরাবর 1 উপাদান পিছনে সরান।
  • বাম দিকে 1 উপাদান সরান।

এর অর্থ হল আমরা সঙ্গে একযোগে একটি একক পরিবর্তনশীল ব্যবহার করতে পারেন firstএবং lastএকটি স্তর মধ্যে সরাতে ভেরিয়েবল। এটি উল্লেখ করতে সহায়তা করতে পারে যে উপরের সারিটি পেরিয়ে ডানদিকে নীচে উভয়কে বাড়ানো দরকার। নীচে বাম দিকে এবং উপরের দিকে পিছনে সরানোর সময় উভয় হ্রাস প্রয়োজন।

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2

    # Move through layers (i.e. layer loop).
    for layer in range(0, layer_count):

            first = layer
            last = size - first - 1

            # Move within a single layer (i.e. element loop).
            for element in range(first, last):

                offset = element - first

                # 'element' increments column (across right)
                top_element = (first, element)
                # 'element' increments row (move down)
                right_side = (element, last)
                # 'last-offset' decrements column (across left)
                bottom = (last, last-offset)
                # 'last-offset' decrements row (move up)
                left_side = (last-offset, first)

                print 'top: %s' % (top)
                print 'right_side: %s' % (right_side)
                print 'bottom: %s' % (bottom)
                print 'left_side: %s' % (left_side)

এখন আমাদের কেবল শীর্ষটি ডান পাশের, নীচে থেকে ডানদিকে, নীচে বাম দিকে এবং বাম দিকটি শীর্ষে নির্ধারিত করতে হবে। এই সব একসাথে রাখা আমরা পেতে:

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2

    for layer in range(0, layer_count):
        first = layer
        last = size - first - 1

        for element in range(first, last):
            offset = element - first

            top = matrix[first][element]
            right_side = matrix[element][last]
            bottom = matrix[last][last-offset]
            left_side = matrix[last-offset][first]

            matrix[first][element] = left_side
            matrix[element][last] = top
            matrix[last][last-offset] = right_side
            matrix[last-offset][first] = bottom

ম্যাট্রিক্স দেওয়া:

0,  1,  2  
3,  4,  5  
6,  7,  8 

আমাদের rotateফাংশন এর ফলাফল:

6,  3,  0  
7,  4,  1  
8,  5,  2  

আমি প্রথম দিকে "বাহ, সর্বোত্তম ব্যাখ্যা" এর মতো অনুভব করেছি তবে কয়েকবার পড়ার পরে (শব্দের সমুদ্রের মধ্যে আমি কোনও গুরুত্বপূর্ণ বিষয় মিস করি না তা নিশ্চিত করার জন্য), আমার মতামত "মানুষ, আমি এটি পেয়েছি," করতে পারি আমরা কি এটি চলমান রাখি দয়া করে? " এখনও এর বিস্তৃত উত্তর রচনা করার জন্য কি ঘন্টা সময় থাকতে হবে তা গ্রহণের জন্য আপত্তি জানানো হয়েছে।
অভিজিৎ সরকার

1
@ অভিজিৎসরকার - আপ-ভোট দেওয়ার জন্য ধন্যবাদ এবং আমি আশা করি এটি কমপক্ষে কিছুটা ছোট উপায়ে সহায়তা করেছে। অবশ্যই, আপনি ঠিক বলেছেন, আমার উত্তরটি শব্দবাচক। এটি যদিও ইচ্ছাকৃতভাবে উত্তরগুলির বিশাল সংখ্যাগরিষ্ঠের বিপরীতে ছিল । যেমনটি আমি আমার উত্তরের একেবারে শুরুতেই বলেছিলাম: "এই উত্তরে মূল ধারণাগুলি পুনরাবৃত্তি হয়, গতি ধীর এবং ইচ্ছাকৃতভাবে পুনরাবৃত্তি হয়।" আপনার যদি এমন সম্পাদনা থাকে যা স্পষ্টতা এবং প্রয়োজনীয় পুনরাবৃত্তি রাখে তবে শব্দ সংখ্যাটি হ্রাস করে, আমি পরামর্শের জন্য খুব খোলা আছি। বা কেবল সম্পাদনা করুন :)
জ্যাক

@ জ্যাক সত্যিই ভাল ব্যাখ্যা। যাইহোক, আমি আন্ডারস্ট্যান্ড করতে পারি না, আপনি কীভাবে অফসেট = এলিমেন্ট - প্রথম এবং শেষ = আকার - প্রথম - 1 নিয়ে এসেছেন? এটি বুঝতে খুব কষ্ট হয়েছে? এছাড়াও, শেষ-অফসেটটি অফসেটের মতো কি?
আশীষ্মেশ্বরম

1
টিএল; ডিআর:list(zip(*reversed(your_list_of_lists)))
বরিস

127

পাইথন:

rotated = list(zip(*original[::-1]))

এবং ঘড়ির কাঁটার বিপরীতে:

rotated_ccw = list(zip(*original))[::-1]

এটি কীভাবে কাজ করে:

zip(*original)তালিকা থেকে সম্পর্কিত তালিকাগুলি নতুন তালিকায় স্ট্যাক করে 2 ডি অ্যারের অক্ষগুলি অদলবদল করবে। ( *অপারেটর অন্তর্ভুক্ত তালিকাগুলি যুক্তিগুলিতে বিতরণ করতে ফাংশনটি বলে)

>>> list(zip(*[[1,2,3],[4,5,6],[7,8,9]]))
[[1,4,7],[2,5,8],[3,6,9]]

[::-1]বিবৃতি উল্টিয়ে অ্যারে উপাদানের (দয়া করে দেখুন সম্প্রসারিত স্লাইস বা এই প্রশ্ন ):

>>> [[1,2,3],[4,5,6],[7,8,9]][::-1]
[[7,8,9],[4,5,6],[1,2,3]]

অবশেষে, দুটি সংমিশ্রণের ফলে ঘূর্ণন রূপান্তর হবে।

স্থাপনের পরিবর্তন [::-1]ম্যাট্রিক্সের বিভিন্ন স্তরের তালিকাগুলি উল্টো করে দেবে।


3
আমি বিশ্বাস করি এই কোডটি পিটার নরভিগ থেকে উত্পন্ন হয়েছে: norvig.com/python-iaq.html
জোসিপ

আপনি মূল তালিকার অতিরিক্ত অনুলিপি তৈরি এড়াতে zip(*reversed(original))পরিবর্তে ব্যবহার করতে পারেন zip(*original[::-1])
বরিস

70

ফলাফলটি রাখার জন্য পুরোপুরি নতুন অ্যারে ব্যবহার না করে স্থানে ঘোরানো এমন এক এখানে রয়েছে। আমি অ্যারের প্রারম্ভিককরণ এবং এটিকে মুদ্রণ করে রেখেছি। এটি কেবল স্কোয়ার অ্যারেগুলির জন্যই কাজ করে তবে সেগুলি যে কোনও আকারের হতে পারে। মেমরির ওভারহেড অ্যারের এক উপাদানের আকারের সমান হয় যাতে আপনি যতটা বড় অ্যারে ঘুরতে পারেন তেমন করতে পারেন।

int a[4][4];
int n = 4;
int tmp;
for (int i = 0; i < n / 2; i++)
{
    for (int j = i; j < n - i - 1; j++)
    {
        tmp             = a[i][j];
        a[i][j]         = a[j][n-i-1];
        a[j][n-i-1]     = a[n-i-1][n-j-1];
        a[n-i-1][n-j-1] = a[n-j-1][i];
        a[n-j-1][i]     = tmp;
    }
}

আমি কমপক্ষে একটি বাগ দেখতে পাচ্ছি। আপনি যদি কোড পোস্ট করতে চলেছেন তবে এটি পরীক্ষা করুন বা কমপক্ষে বলুন যে আপনি এটি করেননি।
হিউ অ্যালেন

1
কোথায়? এটি নির্দেশ করুন এবং আমি এটি ঠিক করব। আমি এটি পরীক্ষা করেছিলাম এবং এটি উভয় এবং এমনকি আকারের অ্যারেগুলিতে দুর্দান্ত কাজ করে।
dagorym

2
এটি একটি সুন্দর সমাধান। উদ্দেশ্য যদি সেট করা হয় তবে মন এই ধরণের পরাস্ত করতে পারে। ও (এন 2) থেকে ও (1)
মুভিফাস্ট

2
এটি ও (1) নয়; এটি এখনও হে (এন ^ 2)
ডুমা

11
এর ও (এন ^ 2) মেমরি ও (1) সহ।
নীল

38

এখানে প্রচুর ভাল কোড রয়েছে তবে আমি কেবল জ্যামিতিকভাবে যা চলছে তা দেখাতে চাই যাতে আপনি কোড যুক্তিকে আরও ভালভাবে বুঝতে পারেন। এখানে আমি কিভাবে এই কাছে যেতে চাই।

প্রথমত, এটিকে স্থানান্তরের সাথে বিভ্রান্ত করবেন না যা খুব সহজ ..

বেসিক ধারণাটি একে স্তর হিসাবে বিবেচনা করা এবং আমরা একবারে একটি স্তর ঘোরাই ...

বলুন আমাদের একটি 4x4 আছে

1   2   3   4
5   6   7   8
9   10  11  12
13  14  15  16

আমরা 90 দ্বারা ঘড়ির কাঁটার দিকে ঘোরার পরে আমরা পাই

13  9   5   1
14  10  6   2   
15  11  7   3
16  12  8   4

সুতরাং আসুন এটির পচা যাক, প্রথমে আমরা মূলত 4 টি কোণটি ঘোরান

1           4


13          16

তারপরে আমরা নীচের ডায়মন্ডটি ঘুরিয়ে দেব যা ধরণের জিজ্ঞাসা

    2
            8
9       
        15

এবং তারপর দ্বিতীয় স্কিউড হীরা

        3
5           
            12
    14

যাতে এটি বাহ্যিক প্রান্তের যত্ন নেয় তাই মূলত আমরা এক সময় পর্যন্ত সেই শেলটি করি

অবশেষে মাঝের বর্গক্ষেত্র (অথবা এটি কেবলমাত্র চূড়ান্ত উপাদান যা সরায় না তা বিজোড় হলে)

6   7
10  11

সুতরাং এখন আসুন প্রতিটি স্তরের সূচকগুলি বের করা যাক, ধরে নিই আমরা সর্বদা বহিরাগত স্তরটির সাথে কাজ করি, আমরা করছি

[0,0] -> [0,n-1], [0,n-1] -> [n-1,n-1], [n-1,n-1] -> [n-1,0], and [n-1,0] -> [0,0]
[0,1] -> [1,n-1], [1,n-2] -> [n-1,n-2], [n-1,n-2] -> [n-2,0], and [n-2,0] -> [0,1]
[0,2] -> [2,n-2], [2,n-2] -> [n-1,n-3], [n-1,n-3] -> [n-3,0], and [n-3,0] -> [0,2]

যতক্ষণ না আমরা প্রান্তের মধ্য দিয়ে অর্ধেক হয়ে

সাধারণভাবে প্যাটার্ন হয়

[0,i] -> [i,n-i], [i,n-i] -> [n-1,n-(i+1)], [n-1,n-(i+1)] -> [n-(i+1),0], and [n-(i+1),0] to [0,i]

"প্রান্ত দিয়ে অর্ধেক" এর অর্থ কী? আমি N / 2 এবং অন্যান্যরা N টি লুপিং অবধি প্রচুর অ্যালগরিদমগুলি দেখতে দেখতে পাচ্ছি, কিন্তু এন / 2 কোথা থেকে আসছে তা আমি দেখতে পাচ্ছি না।
PDN

কোডিং সাক্ষাত্কারটি ক্র্যাক করার ক্ষেত্রে এর একই সমাধানটি আমি বিশ্বাস করি। তবে আমি ধাপে ধাপে ব্যাখ্যা পছন্দ করি। খুব সুন্দর এবং পুরোপুরি।
নেফস্টোর

@ পিডিএন এই উত্তরটি বিস্তারিতভাবে ব্যাখ্যা করেছে।
ম্যাথিয়াস বাইনেস

35

যেমনটি আমি আমার আগের পোস্টে বলেছি, এখানে সি # তে কিছু কোড রয়েছে যা কোনও আকারের ম্যাট্রিক্সের জন্য ও (1) ম্যাট্রিক্স ঘূর্ণন প্রয়োগ করে। ব্রিভিটি এবং পঠনযোগ্যতার জন্য চেক বা রেঞ্জ চেক করার কোনও ত্রুটি নেই। কোড:

static void Main (string [] args)
{
  int [,]
    //  create an arbitrary matrix
    m = {{0, 1}, {2, 3}, {4, 5}};

  Matrix
    //  create wrappers for the data
    m1 = new Matrix (m),
    m2 = new Matrix (m),
    m3 = new Matrix (m);

  //  rotate the matricies in various ways - all are O(1)
  m1.RotateClockwise90 ();
  m2.Rotate180 ();
  m3.RotateAnitclockwise90 ();

  //  output the result of transforms
  System.Diagnostics.Trace.WriteLine (m1.ToString ());
  System.Diagnostics.Trace.WriteLine (m2.ToString ());
  System.Diagnostics.Trace.WriteLine (m3.ToString ());
}

class Matrix
{
  enum Rotation
  {
    None,
    Clockwise90,
    Clockwise180,
    Clockwise270
  }

  public Matrix (int [,] matrix)
  {
    m_matrix = matrix;
    m_rotation = Rotation.None;
  }

  //  the transformation routines
  public void RotateClockwise90 ()
  {
    m_rotation = (Rotation) (((int) m_rotation + 1) & 3);
  }

  public void Rotate180 ()
  {
    m_rotation = (Rotation) (((int) m_rotation + 2) & 3);
  }

  public void RotateAnitclockwise90 ()
  {
    m_rotation = (Rotation) (((int) m_rotation + 3) & 3);
  }

  //  accessor property to make class look like a two dimensional array
  public int this [int row, int column]
  {
    get
    {
      int
        value = 0;

      switch (m_rotation)
      {
      case Rotation.None:
        value = m_matrix [row, column];
        break;

      case Rotation.Clockwise90:
        value = m_matrix [m_matrix.GetUpperBound (0) - column, row];
        break;

      case Rotation.Clockwise180:
        value = m_matrix [m_matrix.GetUpperBound (0) - row, m_matrix.GetUpperBound (1) - column];
        break;

      case Rotation.Clockwise270:
        value = m_matrix [column, m_matrix.GetUpperBound (1) - row];
        break;
      }

      return value;
    }

    set
    {
      switch (m_rotation)
      {
      case Rotation.None:
        m_matrix [row, column] = value;
        break;

      case Rotation.Clockwise90:
        m_matrix [m_matrix.GetUpperBound (0) - column, row] = value;
        break;

      case Rotation.Clockwise180:
        m_matrix [m_matrix.GetUpperBound (0) - row, m_matrix.GetUpperBound (1) - column] = value;
        break;

      case Rotation.Clockwise270:
        m_matrix [column, m_matrix.GetUpperBound (1) - row] = value;
        break;
      }
    }
  }

  //  creates a string with the matrix values
  public override string ToString ()
  {
    int
      num_rows = 0,
      num_columns = 0;

    switch (m_rotation)
    {
    case Rotation.None:
    case Rotation.Clockwise180:
      num_rows = m_matrix.GetUpperBound (0);
      num_columns = m_matrix.GetUpperBound (1);
      break;

    case Rotation.Clockwise90:
    case Rotation.Clockwise270:
      num_rows = m_matrix.GetUpperBound (1);
      num_columns = m_matrix.GetUpperBound (0);
      break;
    }

    StringBuilder
      output = new StringBuilder ();

    output.Append ("{");

    for (int row = 0 ; row <= num_rows ; ++row)
    {
      if (row != 0)
      {
        output.Append (", ");
      }

      output.Append ("{");

      for (int column = 0 ; column <= num_columns ; ++column)
      {
        if (column != 0)
        {
          output.Append (", ");
        }

        output.Append (this [row, column].ToString ());
      }

      output.Append ("}");
    }

    output.Append ("}");

    return output.ToString ();
  }

  int [,]
    //  the original matrix
    m_matrix;

  Rotation
    //  the current view of the matrix
    m_rotation;
}

ঠিক আছে, আমি আমার হাত উপরে রাখব, ঘোরানোর সময় এটি মূল অ্যারেটিতে কোনও পরিবর্তন করে না। তবে, ওও সিস্টেমে যতক্ষণ অবজেক্টটিকে ক্লাসের ক্লায়েন্টদের কাছে ঘোরানো হয়েছে বলে মনে হচ্ছে ততক্ষণ তাতে কিছু যায় আসে না। এই মুহুর্তে, ম্যাট্রিক্স বর্গটি মূল অ্যারে ডেটার উল্লেখগুলি ব্যবহার করে তাই এম 1 এর কোনও মান পরিবর্তন করলে এম 2 এবং এম 3ও পরিবর্তন হবে। নতুন অ্যারে তৈরি করার জন্য কনস্ট্রাক্টরের একটি ছোট পরিবর্তন এবং মানগুলিকে অনুলিপি করে তা সাজিয়ে ফেলবে।


4
বলিহারি! এটি খুব সুন্দর সমাধান এবং কেন জানি এটি গৃহীত উত্তর নয়।
মার্টিনাটিমে

@ মার্টিনাটাইম: সম্ভবত এটি 5 গুণ বড় হিসাবে
টড

@Toad: গতি, আকার, খরচ, ইত্যাদি: ওয়েল, কোড লেখা সবসময় প্রতিদ্বন্দ্বী প্রয়োজনীয়তা মধ্যেও একটা সম্পর্ক হয়
Skizz

15
সত্য ... আরেকটি সমস্যা হ'ল ম্যাট্রিক্স আসলে ঘোরানো হয় না, তবে 'ঠিক সময়ে' আবর্তিত হয়। যা কয়েকটি উপাদানগুলিতে অ্যাক্সেসের জন্য দুর্দান্ত, তবে এই ম্যাট্রিক্সটি গণনা বা চিত্রের ম্যানিপুলেশনে ব্যবহার করা হত ভয়াবহ। সুতরাং ও (1) বলা সত্যিই ন্যায্য নয়।
তুষারপাত

23

তথ্য স্থানে ঘোরানো প্রয়োজন হতে পারে (সম্ভবত শারীরিকভাবে সঞ্চিত প্রতিনিধিত্ব আপডেট করতে), অ্যারে অ্যাক্সেসের মধ্যে ইন্ডিয়ারেশনের একটি স্তর যুক্ত করার জন্য এটি সম্ভবত সহজ এবং সম্ভবত আরও পারফরম্যান্ট হয়ে উঠবে: সম্ভবত একটি ইন্টারফেস:

interface IReadableMatrix
{
    int GetValue(int x, int y);
}

যদি আপনি Matrixইতিমধ্যে এই ইন্টারফেসটি প্রয়োগ করেন, তবে এটি এর মতো একটি সজ্জা শ্রেণীর মাধ্যমে ঘোরানো যেতে পারে :

class RotatedMatrix : IReadableMatrix
{
    private readonly IReadableMatrix _baseMatrix;

    public RotatedMatrix(IReadableMatrix baseMatrix)
    {
        _baseMatrix = baseMatrix;
    }

    int GetValue(int x, int y)
    {
        // transpose x and y dimensions
        return _baseMatrix(y, x);
    }
}

+ 90 / -90 / 180 ডিগ্রি ঘোরানো, অনুভূমিকভাবে / উল্লম্বভাবে উল্টানো এবং স্কেলিং সমস্ত এই ফ্যাশনেও অর্জন করা যায়।

পারফরম্যান্সটি আপনার নির্দিষ্ট দৃশ্যে পরিমাপ করা দরকার। তবে ও (এন ^ 2) অপারেশনটি এখন একটি ও (1) কল দিয়ে প্রতিস্থাপন করা হয়েছে। এটা একটা ভার্চুয়াল পদ্ধতি কল যা এর হয় সরাসরি অ্যারে এক্সেস তুলনায় ধীর, তাই এটি কত ঘন ঘন আবর্তিত অ্যারের ঘূর্ণন পরে ব্যবহার করা হয় উপর নির্ভর করে। যদি এটি একবার ব্যবহার করা হয়, তবে অবশ্যই এই পদ্ধতির জয় হবে। যদি এটি ঘোরানো হয় তবে কয়েক দিন ধরে চলমান সিস্টেমে ব্যবহৃত হয়, তবে স্থানস্থ ঘোরানো আরও ভালভাবে সম্পাদন করতে পারে। আপনি আপ-ফ্রন্ট ব্যয়টি গ্রহণ করতে পারবেন কিনা তাও এটি নির্ভর করে।

সমস্ত পারফরম্যান্স ইস্যু হিসাবে, পরিমাপ, পরিমাপ, পরিমাপ!


1
+1 ... এবং যদি ম্যাট্রিক্সটি সত্যিই বড় হয় এবং আপনি কেবল কয়েকটি উপাদান ব্যবহার করেন (বিরল ব্যবহার) এটি আরও বেশি কার্যকর
লুথর

16
এটিকে একটি ও (1) সময় সমাধান বলে মনে করা কিছুটা অন্যায় বলে মনে হচ্ছে। ওপি দ্বারা উত্থিত সমস্যা সমাধানের জন্য এটি এখনও ও (n ^ 2) সময় নিতে পারে। শুধু তাই নয়, এটি সমস্যার সমাধান করবে না কারণ এটি ট্রান্সপোজ ফিরিয়ে দেয় । প্রদত্ত উদাহরণটির সমাধান হিসাবে ট্রান্সপোজ নেই।
ইম্পালা

5
এখন, আপনি যদি ম্যাট্রিক্সের প্রথম 3 উপাদানগুলি চেয়েছিলেন তবে এটি একটি সূক্ষ্ম সমাধান, তবে সমস্যাটি হ'ল সম্পূর্ণ রূপান্তরিত ম্যাট্রিক্স পুনরুদ্ধার করা (অর্থাৎ ধরে নিবেন যে আপনার সমস্ত ম্যাট্রিক্স উপাদান প্রয়োজন)। এটিকে (1) কল করা হল অ্যালগরিদম বিশ্লেষণের ক্রেডিট ডিফল্ট অদলবদল পদ্ধতি - আপনি সমস্যার সমাধান করেননি, আপনি একে অন্য কারও দিকে ঠেলে দিয়েছেন :)
আনা বেটস

4
@ পল বাজেস: আমি আপনার বক্তব্যটি পেয়েছি, তবে আমি উপরে মতামতগুলিতে লিখেছি যেমন আপনি ম্যাট্রিক্স স্থানান্তরিত করেছেন এমনকি যদি আপনি মানগুলি পড়তে চান তবে আপনাকে লুপটি লিখতে হবে। সুতরাং ম্যাট্রিক্স থেকে সমস্ত মান পড়া সর্বদা O (N ^ 2) নির্বিশেষে is এখানে পার্থক্যটি হ'ল আপনি যদি স্থানান্তর, ঘোরানো, স্কেল, স্কেল আবার ইত্যাদি করেন তবে আপনি কেবল একবার O (N ^ 2) একবার আঘাত করেন। যেমনটি আমি বলেছিলাম, এটি সর্বদা সেরা সমাধান নয়, তবে বেশিরভাগ ক্ষেত্রেই এটি উপযুক্ত এবং সার্থক। ওপি মনে হয়েছিল যে কোনও যাদু সমাধান সন্ধান করছে এবং এটি আপনি যতটা কাছে পাবেন তত কাছাকাছি।
ড্র নোকস

9
আমি এই উত্তরটি পছন্দ করি তবে আমি কিছু উল্লেখ করতে চাই। সজ্জিত ম্যাট্রিক্সের মুদ্রণ করা (এবং সাধারণভাবে অন্যান্য ক্রম অনুসারে পাঠ করা) ম্যাট্রিক্সের সাথে মেমরির আবর্তিত করা একই কাজ করার চেয়ে অনেক ধীর হতে পারে এবং এটি কেবল ভার্চুয়াল পদ্ধতি কলগুলির কারণে নয়। বড় ম্যাট্রিক্সের জন্য, আপনি "ওপারে" না হয়ে "ডাউন" পড়ে আপনি যে ক্যাশে মিস করেছেন তার সংখ্যা ব্যাপকভাবে বাড়িয়ে চলেছেন।
মাইক ড্যানিয়েলস

18

জাভাতে এটির এটির আরও ভাল সংস্করণ: আমি এটি আলাদা প্রস্থ এবং উচ্চতা সহ ম্যাট্রিক্সের জন্য তৈরি করেছি

  • এইচটি এখানে ঘোরার পরে ম্যাট্রিক্সের উচ্চতা
  • ডাব্লু এখানে ঘোরার পরে ম্যাট্রিক্সের প্রস্থ রয়েছে

 

public int[][] rotateMatrixRight(int[][] matrix)
{
    /* W and H are already swapped */
    int w = matrix.length;
    int h = matrix[0].length;
    int[][] ret = new int[h][w];
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            ret[i][j] = matrix[w - j - 1][i];
        }
    }
    return ret;
}


public int[][] rotateMatrixLeft(int[][] matrix)
{
    /* W and H are already swapped */
    int w = matrix.length;
    int h = matrix[0].length;   
    int[][] ret = new int[h][w];
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            ret[i][j] = matrix[j][h - i - 1];
        }
    }
    return ret;
}

এই কোড নিক বেরার্ডির পোস্টের উপর ভিত্তি করে।


ধন্যবাদ। এটি এখানে পরিষ্কার জাভা কোড ছিল। প্রশ্ন - আপনি / নিক কীভাবে [w - j - 1] অংশ নিয়ে এসেছেন? @ জাগ্রত উত্তরের দিকে তাকানো আমি দেখতে পাচ্ছি যে আপনি কীভাবে আনয়ন / সমাধানের উদাহরণগুলির মাধ্যমে তা অর্জন করতে পারেন। কীভাবে এটি প্রাপ্ত হয়েছিল তা ম্যাট্রিক্স সম্পর্কিত কিছু গাণিতিক নীতির উপর ভিত্তি করে কিনা তা ভাবছেন।
কোয়েস্ট Monger

17

রুবি-ওয়ে: .transpose.map &:reverse


1
এটি তার চেয়েও সহজ: array.reverse.transposeএকটি অ্যারেরকে ঘড়ির কাঁটার দিকে array.transpose.reverseঘোরায় , যখন এটি ঘড়ির কাঁটার বিপরীতে ঘোরায়। দরকার নেই map
জর্জি গিরিশভিলি

13

ইতিমধ্যে প্রচুর উত্তর রয়েছে এবং আমি দুটি দাবিদার ও (1) সময়ের জটিলতা পেয়েছি। বাস্তব হে (1) অ্যালগরিদম অ্যারের স্টোরেজ অস্পৃষ্ট ছেড়ে, এবং পরিবর্তন কিভাবে আপনি সূচক তার উপাদান হয়। এখানে লক্ষ্যটি হ'ল এটি অতিরিক্ত মেমরি গ্রাস করে না, আবার ডেটা পুনরুক্ত করতে অতিরিক্ত সময় প্রয়োজন হয় না।

90, -90 এবং 180 ডিগ্রির আবর্তনগুলি সরল রূপান্তর যা আপনি যতক্ষণ জানেন যে আপনার 2 ডি অ্যারেতে কতগুলি সারি এবং কলাম রয়েছে তা করা যেতে পারে; যে কোনও ভেক্টরকে 90 ডিগ্রি ঘোরানোর জন্য, অক্ষগুলি অদলবদল করুন এবং Y অক্ষকে তুচ্ছ করুন। -90 ডিগ্রির জন্য, অক্ষগুলি অদলবদল করুন এবং এক্স অক্ষটিকে অস্বীকার করুন। 180 ডিগ্রির জন্য, অদলবদল না করে উভয় অক্ষকে অবহেলা করুন।

আরও রূপান্তর সম্ভব, যেমন অনুভূমিকভাবে এবং / অথবা উল্লম্বভাবে অক্ষগুলি অবহেলা করে স্বতন্ত্রভাবে মিরর করা।

এটি উদাহরণস্বরূপ একটি অ্যাক্সেসর পদ্ধতির মাধ্যমে করা যেতে পারে। নীচের উদাহরণগুলি জাভাস্ক্রিপ্ট ফাংশন, তবে ধারণাগুলি সমস্ত ভাষায় সমানভাবে প্রযোজ্য।

 // Get an array element in column/row order
 var getArray2d = function(a, x, y) {
   return a[y][x];
 };

 //demo
 var arr = [
   [5, 4, 6],
   [1, 7, 9],
   [-2, 11, 0],
   [8, 21, -3],
   [3, -1, 2]
 ];

 var newarr = [];
 arr[0].forEach(() => newarr.push(new Array(arr.length)));

 for (var i = 0; i < newarr.length; i++) {
   for (var j = 0; j < newarr[0].length; j++) {
     newarr[i][j] = getArray2d(arr, i, j);
   }
 }
 console.log(newarr);

// Get an array element rotated 90 degrees clockwise
function getArray2dCW(a, x, y) {
  var t = x;
  x = y;
  y = a.length - t - 1;
  return a[y][x];
}

//demo
var arr = [
  [5, 4, 6],
  [1, 7, 9],
  [-2, 11, 0],
  [8, 21, -3],
  [3, -1, 2]
];

var newarr = [];
arr[0].forEach(() => newarr.push(new Array(arr.length)));

for (var i = 0; i < newarr[0].length; i++) {
  for (var j = 0; j < newarr.length; j++) {
    newarr[j][i] = getArray2dCW(arr, i, j);
  }
}
console.log(newarr);

// Get an array element rotated 90 degrees counter-clockwise
function getArray2dCCW(a, x, y) {
  var t = x;
  x = a[0].length - y - 1;
  y = t;
  return a[y][x];
}

//demo
var arr = [
  [5, 4, 6],
  [1, 7, 9],
  [-2, 11, 0],
  [8, 21, -3],
  [3, -1, 2]
];

var newarr = [];
arr[0].forEach(() => newarr.push(new Array(arr.length)));

for (var i = 0; i < newarr[0].length; i++) {
  for (var j = 0; j < newarr.length; j++) {
    newarr[j][i] = getArray2dCCW(arr, i, j);
  }
}
console.log(newarr);

// Get an array element rotated 180 degrees
function getArray2d180(a, x, y) {
  x = a[0].length - x - 1;
  y = a.length - y - 1;
  return a[y][x];
}

//demo
var arr = [
  [5, 4, 6],
  [1, 7, 9],
  [-2, 11, 0],
  [8, 21, -3],
  [3, -1, 2]
];

var newarr = [];
arr.forEach(() => newarr.push(new Array(arr[0].length)));

for (var i = 0; i < newarr[0].length; i++) {
  for (var j = 0; j < newarr.length; j++) {
    newarr[j][i] = getArray2d180(arr, i, j);
  }
}
console.log(newarr);

এই কোডটি নেস্টেড অ্যারেগুলির একটি অ্যারে ধরে নেয়, যেখানে প্রতিটি অভ্যন্তরীণ অ্যারে একটি সারি হয়।

পদ্ধতিটি আপনাকে উপাদানগুলি (বা লিখতে) অনুমতি দেয় (এমনকি এলোমেলো ক্রমে) যেন অ্যারেটি ঘোরানো হয়েছে বা রূপান্তরিত হয়েছে। এখন কেবলমাত্র রেফারেন্স অনুসারে কল করার জন্য সঠিক ফাংশনটি বেছে নিন এবং আপনি চলে যাবেন!

এক্সেসর পদ্ধতির মাধ্যমে সংযোজন (এবং অ-ধ্বংসাত্মক) রূপান্তর প্রয়োগের জন্য ধারণাটি বাড়ানো যেতে পারে। নির্বিচারে কোণ ঘোরানো এবং স্কেলিং সহ।


এগুলির কিছুই আসলে আসল অ্যারে থেকে ঘোরানো হয়নি। প্রথমটি, শেষ ফলাফলটি কেবল স্থানান্তরিত হয়। দ্বিতীয়টি, আপনি কেবল সারি সরিয়ে ফেলেছেন বা অনুভূমিক কেন্দ্র জুড়ে মিরর করেছেন। তৃতীয়, আপনি কেবল সারিগুলি বিপরীত করেছেন এবং চতুর্থটিও স্থানান্তরিত হয়েছে। যার কোনটিই আসলে "ঘোরানো" ছিল না।
এসএম 177 ই

দ্বিতীয় দুটি উদাহরণে কিছু বাগ রয়েছে। ত্রুটি ঠিক করা। আমি স্পষ্টভাবে উল্লেখ করেছে যে এই সমাধান না একটি ইন-জায়গা ঘূর্ণন। এটি একটি রূপান্তর ফাংশন, যা এটি অলস পুনরাবৃত্তির জন্য উপযুক্ত করে তোলে।
জেসন ওস্টার

কোনও আবর্তন ব্যতীত যাতে আপনি ওপি যা জিজ্ঞাসা করেছিল তা আসলে জবাব দেয়নি।
SM177Y

@ SM177Y অন্য সম্পাদক আমার উত্তরে অ-কার্যকারী উদাহরণ কোড যুক্ত করেছেন। আমি দেখতে পাচ্ছি আপনি কীভাবে এতে বিভ্রান্ত হয়ে পড়েছিলেন। আমি পুনরাবৃত্তি লুপগুলিতে বাগগুলি স্থির করেছি। প্রদত্ত ফাংশনগুলি আসলে অ্যারেতে ডেটা "আবর্তিত" করে।
জেসন ওস্টার

এছাড়াও গুরুত্বপূর্ণ বিশদটি হ'ল উদাহরণ কোডটি আমার দেওয়া মূল উত্তরটিকে সত্যিই ধুয়ে দেয়, যা লিনিয়ার স্পেস-টাইম জটিলতার সমাধানগুলিতে ক্রিয়ামূলক রূপান্তরকরণের শক্তি চিত্রিত করার চেষ্টা করছিল। কার্যকরী রূপান্তরের মাধ্যমে আপনি ইতিমধ্যে পুনরাবৃত্তি করছেন বা অন্যথায় অ্যারে উপাদানগুলিতে অ্যাক্সেস করছেন , সুতরাং ধ্রুবক স্থান এবং সময়ের জটিলতার অর্থে রূপান্তরটিকে "মুক্ত" হিসাবে বিবেচনা করা হয়।
জেসন ওস্টার

10

কিছু লোক ইতিমধ্যে উদাহরণ স্থাপন করেছে যার মধ্যে একটি নতুন অ্যারে তৈরি করা জড়িত।

আরও কয়েকটি বিষয় বিবেচনা করুন:

(ক) প্রকৃতপক্ষে ডেটা স্থানান্তরিত করার পরিবর্তে, "ঘোরানো" অ্যারেটিকে আলাদাভাবে অতিক্রম করুন।

(খ) জায়গায় ঘোরানোটি একটু কৌশলযুক্ত হতে পারে। আপনার কিছুটা স্ক্র্যাচ জায়গা প্রয়োজন হবে (সম্ভবত প্রায় এক সারি বা আকারের কলামের সমান)। ইন-প্লেস ট্রান্সপোজ ( http://doi.acm.org/10.1145/355719.355729 ) করার বিষয়ে একটি প্রাচীন এসিএম কাগজ রয়েছে , তবে তাদের উদাহরণ কোডটি নোংরা গোটো-বোঝা ফরট্রান।

সংযোজন:

http://doi.acm.org/10.1145/355611.355612 হ'ল স্থান, ট্রান্সপোজ অ্যালগরিদম, অন্যরকম বলে মনে করা যায় superior


আমি এটার সাথে একমত. এমন একটি পদ্ধতি রয়েছে যা উত্স ডেটা এবং "ঘোরানো" ডেটার মধ্যে অনুবাদ নির্ধারণ করে।
মার্টিনাটিমে

8

নিকের উত্তরটি কোনও এনএক্সএম অ্যারের পক্ষেও কাজ করবে কেবলমাত্র একটি ছোট্ট পরিবর্তন (কোনও এনএক্সএন-এর বিপরীতে)।

string[,] orig = new string[n, m];
string[,] rot = new string[m, n];

...

for ( int i=0; i < n; i++ )
  for ( int j=0; j < m; j++ )
    rot[j, n - i - 1] = orig[i, j];

এটি সম্পর্কে চিন্তা করার একটি উপায় হ'ল আপনি অক্ষের কেন্দ্র (0,0) উপরের বাম কোণ থেকে উপরের ডান কোণে সরিয়ে নিয়েছেন। আপনি কেবল এক থেকে অন্যটিতে স্থানান্তর করছেন ing


6

সময় - ও (এন), স্থান - ও (1)

public void rotate(int[][] matrix) {
    int n = matrix.length;
    for (int i = 0; i < n / 2; i++) {
        int last = n - 1 - i;
        for (int j = i; j < last; j++) {
            int top = matrix[i][j];
            matrix[i][j] = matrix[last - j][i];
            matrix[last - j][i] = matrix[last][last - j];
            matrix[last][last - j] = matrix[j][last];
            matrix[j][last] = top;
        }
    }
}

এটি ও (1) নয়। এটি ও (এন)।
জেসন ওস্টার

@ জেসনঅস্টার আমি বিশ্বাস করি যে এটি ও (1) স্থান, কারণ এটি কোনও অতিরিক্ত জায়গা ব্যয় করে না।
flledgling

আমার ভুল ও (1) স্থান জটিলতা, হ্যাঁ। ও (এন) সময়ের জটিলতা।
জেসন ওস্টার

স্পেস কমপ্লেক্সিটি হ'ল ও (এন)। স্পেস জটিলতা ইনপুট ভেরিয়েবল আকারের স্থান অন্তর্ভুক্ত করা উচিত। careercup.com/question?id=14952322
জেসন হিও

ঘড়ির কাঁটার বিপরীতে ঘোরার জন্য আমি কীভাবে এটি পরিবর্তন করতে পারি?
এমডি এক্সএফ

5

এখানে আমার রুবি সংস্করণ (মানগুলি একইরূপে প্রদর্শিত হয় না তা নোট করুন, তবে এটি বর্ণিত হিসাবে ঘোরানো)।

def rotate(matrix)
  result = []
  4.times { |x|
    result[x] = []
    4.times { |y|
      result[x][y] = matrix[y][3 - x]
    }
  }

  result
end

matrix = []
matrix[0] = [1,2,3,4]
matrix[1] = [5,6,7,8]
matrix[2] = [9,0,1,2]
matrix[3] = [3,4,5,6]

def print_matrix(matrix)
  4.times { |y|
    4.times { |x|
      print "#{matrix[x][y]} "
    }
    puts ""
  }
end

print_matrix(matrix)
puts ""
print_matrix(rotate(matrix))

আউটপুট:

1 5 9 3 
2 6 0 4 
3 7 1 5 
4 8 2 6 

4 3 2 1 
8 7 6 5 
2 1 0 9 
6 5 4 3

4

এখানে কেবলমাত্র স্কোয়ারের জন্য জাভা দ্বারা একটি স্পেস-এ ঘোরানো পদ্ধতি। নন-স্কোয়ার 2 ডি অ্যারের জন্য আপনাকে যেভাবেই নতুন অ্যারে তৈরি করতে হবে।

private void rotateInSpace(int[][] arr) {
    int z = arr.length;
    for (int i = 0; i < z / 2; i++) {
        for (int j = 0; j < (z / 2 + z % 2); j++) {
            int x = i, y = j;
            int temp = arr[x][y];
            for (int k = 0; k < 4; k++) {
                int temptemp = arr[y][z - x - 1];
                arr[y][z - x - 1] = temp;
                temp = temptemp;

                int tempX = y;
                y = z - x - 1;
                x = tempX;
            }
        }
    }
}

নতুন অ্যারে তৈরি করে কোনও আকার 2 ডি অ্যারে ঘোরানোর কোড:

private int[][] rotate(int[][] arr) {
    int width = arr[0].length;
    int depth = arr.length;
    int[][] re = new int[width][depth];
    for (int i = 0; i < depth; i++) {
        for (int j = 0; j < width; j++) {
            re[j][depth - i - 1] = arr[i][j];
        }
    }
    return re;
}

3

জাভাস্ক্রিপ্টে ডিম্পল এর +90 সিউডোকোড (যেমন ট্রান্সপোজ তারপর প্রতিটি সারি বিপরীত) প্রয়োগ:

function rotate90(a){
  // transpose from http://www.codesuck.com/2012/02/transpose-javascript-array-in-one-line.html
  a = Object.keys(a[0]).map(function (c) { return a.map(function (r) { return r[c]; }); });
  // row reverse
  for (i in a){
    a[i] = a[i].reverse();
  }
  return a;
}

3

আপনি এটি 3 সহজ পদক্ষেপে করতে পারেন :

1 ) ধরুন আমাদের একটি ম্যাট্রিক্স রয়েছে

   1 2 3
   4 5 6
   7 8 9

) ম্যাট্রিক্সের ট্রান্সপোজ নিন

   1 4 7
   2 5 8
   3 6 9

3 ) ঘূর্ণিত ম্যাট্রিক্স পেতে সারি ইন্টারচেঞ্জ করুন

   3 6 9
   2 5 8
   1 4 7

এর জন্য জাভা সোর্স কোড :

public class MyClass {

    public static void main(String args[]) {
        Demo obj = new Demo();
        /*initial matrix to rotate*/
        int[][] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
        int[][] transpose = new int[3][3]; // matrix to store transpose

        obj.display(matrix);              // initial matrix

        obj.rotate(matrix, transpose);    // call rotate method
        System.out.println();
        obj.display(transpose);           // display the rotated matix
    }
}

class Demo {   
    public void rotate(int[][] mat, int[][] tran) {

        /* First take the transpose of the matrix */
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat.length; j++) {
                tran[i][j] = mat[j][i]; 
            }
        }

        /*
         * Interchange the rows of the transpose matrix to get rotated
         * matrix
         */
        for (int i = 0, j = tran.length - 1; i != j; i++, j--) {
            for (int k = 0; k < tran.length; k++) {
                swap(i, k, j, k, tran);
            }
        }
    }

    public void swap(int a, int b, int c, int d, int[][] arr) {
        int temp = arr[a][b];
        arr[a][b] = arr[c][d];
        arr[c][d] = temp;    
    }

    /* Method to display the matrix */
    public void display(int[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }
}

আউটপুট:

1 2 3 
4 5 6 
7 8 9 

3 6 9 
2 5 8 
1 4 7 

2

এটি আমার বাস্তবায়ন, সি, ও (1) মেমরির জটিলতায়, স্থান ঘোরানোর ক্ষেত্রে, 90 ডিগ্রি ঘড়ির কাঁটার দিকে:

#include <stdio.h>

#define M_SIZE 5

static void initMatrix();
static void printMatrix();
static void rotateMatrix();

static int m[M_SIZE][M_SIZE];

int main(void){
    initMatrix();
    printMatrix();
    rotateMatrix();
    printMatrix();

    return 0;
}

static void initMatrix(){
    int i, j;

    for(i = 0; i < M_SIZE; i++){
        for(j = 0; j < M_SIZE; j++){
            m[i][j] = M_SIZE*i + j + 1;
        }
    }
}

static void printMatrix(){
    int i, j;

    printf("Matrix\n");
    for(i = 0; i < M_SIZE; i++){
        for(j = 0; j < M_SIZE; j++){
            printf("%02d ", m[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

static void rotateMatrix(){
    int r, c;

    for(r = 0; r < M_SIZE/2; r++){
        for(c = r; c < M_SIZE - r - 1; c++){
            int tmp = m[r][c];

            m[r][c] = m[M_SIZE - c - 1][r];
            m[M_SIZE - c - 1][r] = m[M_SIZE - r - 1][M_SIZE - c - 1];
            m[M_SIZE - r - 1][M_SIZE - c - 1] = m[c][M_SIZE - r - 1];
            m[c][M_SIZE - r - 1] = tmp;
        }
    }
}

2

জাভা সংস্করণটি এখানে:

public static void rightRotate(int[][] matrix, int n) {
    for (int layer = 0; layer < n / 2; layer++) {
        int first = layer;
        int last = n - 1 - first;
        for (int i = first; i < last; i++) {
           int offset = i - first;
           int temp = matrix[first][i];
           matrix[first][i] = matrix[last-offset][first];
           matrix[last-offset][first] = matrix[last][last-offset];
           matrix[last][last-offset] = matrix[i][last];
           matrix[i][last] = temp;
        }
    }
}

পদ্ধতিটি প্রথমে মোস্টাউটার স্তরটি ঘোরান, তারপরে স্কোটিটিয়ালি অভ্যন্তরীণ স্তরটিতে যান।


2

রৈখিক দৃষ্টিকোণ থেকে ম্যাট্রিকগুলি বিবেচনা করুন:

    1 2 3        0 0 1
A = 4 5 6    B = 0 1 0
    7 8 9        1 0 0

এবার একটি ট্রান্সপোজ নিন

     1 4 7
A' = 2 5 8
     3 6 9

এবং '' অন বি, বা বি 'এ' এর ক্রিয়া বিবেচনা করুন।
যথাক্রমে:

      7 4 1          3 6 9
A'B = 8 5 2    BA' = 2 5 8
      9 6 3          1 4 7

এটি কোনও এনএক্সএন ম্যাট্রিক্সের জন্য প্রসারণযোগ্য। এবং কোডে এই ধারণাটি দ্রুত প্রয়োগ করা:

void swapInSpace(int** mat, int r1, int c1, int r2, int c2)
{
    mat[r1][c1] ^= mat[r2][c2];
    mat[r2][c2] ^= mat[r1][c1];
    mat[r1][c1] ^= mat[r2][c2];
}

void transpose(int** mat, int size)
{
    for (int i = 0; i < size; i++)
    {
        for (int j = (i + 1); j < size; j++)
        {
            swapInSpace(mat, i, j, j, i);
        }
    }
}

void rotate(int** mat, int size)
{
    //Get transpose
    transpose(mat, size);

    //Swap columns
    for (int i = 0; i < size / 2; i++)
    {
        for (int j = 0; j < size; j++)
        {
            swapInSpace(mat, i, j, size - (i + 1), j);
        }
    }
}

2

ঘোরানোর জন্য সি # কোড [এন, এম] 2 ডি 90 ডিগ্রি ডানদিকে অ্যারে করে

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MatrixProject
{
    // mattrix class

    class Matrix{
        private int rows;
        private int cols;
        private int[,] matrix;

        public Matrix(int n){
            this.rows = n;
            this.cols = n;
            this.matrix = new int[this.rows,this.cols];

        }

        public Matrix(int n,int m){
            this.rows = n;
            this.cols = m;

            this.matrix = new int[this.rows,this.cols];
        }

        public void Show()
        {
            for (var i = 0; i < this.rows; i++)
            {
                for (var j = 0; j < this.cols; j++) {
                    Console.Write("{0,3}", this.matrix[i, j]);
                }
                Console.WriteLine();
            }                
        }

        public void ReadElements()
        {
           for (var i = 0; i < this.rows; i++)
                for (var j = 0; j < this.cols; j++)
                {
                    Console.Write("element[{0},{1}]=",i,j);
                    this.matrix[i, j] = Convert.ToInt32(Console.ReadLine());
                }            
        }


        // rotate [n,m] 2D array by 90 deg right
        public void Rotate90DegRight()
        {

            // create a mirror of current matrix
            int[,] mirror = this.matrix;

            // create a new matrix
            this.matrix = new int[this.cols, this.rows];

            for (int i = 0; i < this.rows; i++)
            {
                for (int j = 0; j < this.cols; j++)
                {
                    this.matrix[j, this.rows - i - 1] = mirror[i, j];
                }
            }

            // replace cols count with rows count
            int tmp = this.rows;
            this.rows = this.cols;
            this.cols = tmp;           
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Matrix myMatrix = new Matrix(3,4);
            Console.WriteLine("Enter matrix elements:");
            myMatrix.ReadElements();
            Console.WriteLine("Matrix elements are:");
            myMatrix.Show();
            myMatrix.Rotate90DegRight();
            Console.WriteLine("Matrix rotated at 90 deg are:");
            myMatrix.Show();
            Console.ReadLine();
        }
    }
}

ফলাফল:

    Enter matrix elements:
    element[0,0]=1
    element[0,1]=2
    element[0,2]=3
    element[0,3]=4
    element[1,0]=5
    element[1,1]=6
    element[1,2]=7
    element[1,3]=8
    element[2,0]=9
    element[2,1]=10
    element[2,2]=11
    element[2,3]=12
    Matrix elements are:
      1  2  3  4
      5  6  7  8
      9 10 11 12
    Matrix rotated at 90 deg are:
      9  5  1
     10  6  2
     11  7  3
     12  8  4

2

পিএইচপি:

<?php    
$a = array(array(1,2,3,4),array(5,6,7,8),array(9,0,1,2),array(3,4,5,6));
$b = array(); //result

while(count($a)>0)
{
    $b[count($a[0])-1][] = array_shift($a[0]);
    if (count($a[0])==0)
    {
         array_shift($a);
    }
}

পিএইচপি 5.6 থেকে অ্যারে ট্রান্সপোসেশনটি একটি দুর্দান্ত array_map()কল দিয়ে সম্পাদন করা যেতে পারে । অন্য কথায়, কলামগুলি সারিগুলিতে রূপান্তরিত হয়।

কোড: ( ডেমো )

$array = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 0, 1, 2],
    [3, 4, 5, 6]
];
$transposed = array_map(null, ...$array);

পক্ষান্তরিত $:

[
    [1, 5, 9, 3],
    [2, 6, 0, 4],
    [3, 7, 1, 5],
    [4, 8, 2, 6]
]

1

For i:= 0 to X do For j := 0 to X do graphic[j][i] := graphic2[X-i][j]

এক্স গ্রাফিকটি থাকা অ্যারের আকার is


1

# ট্রান্সপোজ হ'ল রুবির অ্যারে শ্রেণির একটি মানক পদ্ধতি, এভাবে:

% irb
irb(main):001:0> m = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 0, 1, 2], [3, 4, 5, 6]]
=> [[1, 2, 3, 4], [5, 6, 7, 8], [9, 0, 1, 2], [3, 4, 5, 6]] 
irb(main):002:0> m.reverse.transpose
=> [[3, 9, 5, 1], [4, 0, 6, 2], [5, 1, 7, 3], [6, 2, 8, 4]]

বাস্তবায়নটি সি তে লেখা একটি এন ^ 2 ট্রান্সপোজেশন ফাংশন এটি আপনি এখানে দেখতে পাবেন: "ক্লিক করে" ক্লিক করে http://www.ruby-doc.org/core-1.9.3/Array.html#method-i- ট্রান্সপোজ "ট্রান্সপোজ" এর পাশে "উত্স টগল করতে"।

আমি ও (এন ^ 2) সমাধানগুলির চেয়ে ভাল মনে করতে পারি তবে কেবল বিশেষভাবে নির্মিত ম্যাট্রিক্সের জন্য (যেমন স্পার্স ম্যাট্রিক্স)


1

ম্যাট্রিক্স রোটেশনের জন্য সি কোড যে কোনও এম * এন ম্যাট্রিক্সের জন্য 90 ডিগ্রি ঘড়ির কাঁটার দিকে

void rotateInPlace(int * arr[size][size], int row, int column){
    int i, j;
    int temp = row>column?row:column;
    int flipTill = row < column ? row : column;
    for(i=0;i<flipTill;i++){
        for(j=0;j<i;j++){
            swapArrayElements(arr, i, j);
        }
    }

    temp = j+1;

    for(i = row>column?i:0; i<row; i++){
            for(j=row<column?temp:0; j<column; j++){
                swapArrayElements(arr, i, j);
            }
    }

    for(i=0;i<column;i++){
        for(j=0;j<row/2;j++){
            temp = arr[i][j];
            arr[i][j] = arr[i][row-j-1];
            arr[i][row-j-1] = temp;
        }
    }
}

1

এখানে আমার সিটিতে আমার প্লেস বাস্তবায়ন

void rotateRight(int matrix[][SIZE], int length) {

    int layer = 0;

    for (int layer = 0; layer < length / 2; ++layer) {

        int first = layer;
        int last = length - 1 - layer;

        for (int i = first; i < last; ++i) {

            int topline = matrix[first][i];
            int rightcol = matrix[i][last];
            int bottomline = matrix[last][length - layer - 1 - i];
            int leftcol = matrix[length - layer - 1 - i][first];

            matrix[first][i] = leftcol;
            matrix[i][last] = topline;
            matrix[last][length - layer - 1 - i] = rightcol;
            matrix[length - layer - 1 - i][first] = bottomline;
        }
    }
}

1

এখানে ম্যাট্রিক্স 90 ডিগ্রি রোটেশনের জন্য আমার প্রচেষ্টা যা সিতে 2 ধাপের সমাধান First

#define ROWS        5
#define COLS        5

void print_matrix_b(int B[][COLS], int rows, int cols) 
{
    for (int i = 0; i <= rows; i++) {
        for (int j = 0; j <=cols; j++) {
            printf("%d ", B[i][j]);
        }
        printf("\n");
    }
}

void swap_columns(int B[][COLS], int l, int r, int rows)
{
    int tmp;
    for (int i = 0; i <= rows; i++) {
        tmp = B[i][l];
        B[i][l] = B[i][r];
        B[i][r] = tmp;
    }
}


void matrix_2d_rotation(int B[][COLS], int rows, int cols)
{
    int tmp;
    // Transpose the matrix first
    for (int i = 0; i <= rows; i++) {
        for (int j = i; j <=cols; j++) {
            tmp = B[i][j];
            B[i][j] = B[j][i];
            B[j][i] = tmp;
        }
    }
    // Swap the first and last col and continue until
    // the middle.
    for (int i = 0; i < (cols / 2); i++)
        swap_columns(B, i, cols - i, rows);
}



int _tmain(int argc, _TCHAR* argv[])
{
    int B[ROWS][COLS] = { 
                  {1, 2, 3, 4, 5}, 
                      {6, 7, 8, 9, 10},
                          {11, 12, 13, 14, 15},
                          {16, 17, 18, 19, 20},
                          {21, 22, 23, 24, 25}
                        };

    matrix_2d_rotation(B, ROWS - 1, COLS - 1);

    print_matrix_b(B, ROWS - 1, COLS -1);
    return 0;
}

1

@ ডাগরিম: ও, মানুষ আমি এটিকে "আমি বিরক্ত করছি, আমি কী চিন্তা করতে পারি" ধাঁধাটি হিসাবে এটির জন্য ঝুলিয়ে রেখেছিলাম। আমি আমার স্থানের স্থানান্তর কোডটি নিয়ে এসেছি, তবে তোমার কাছে আমার চেয়ে বেশ সাদৃশ্য খুঁজে পেতে এখানে এসেছি ... আহা, ভাল। এখানে এটি রুবিতে রয়েছে।

require 'pp'
n = 10
a = []
n.times { a << (1..n).to_a }

pp a

0.upto(n/2-1) do |i|
  i.upto(n-i-2) do |j|
    tmp             = a[i][j]
    a[i][j]         = a[n-j-1][i]
    a[n-j-1][i]     = a[n-i-1][n-j-1]
    a[n-i-1][n-j-1] = a[j][n-i-1]
    a[j][n-i-1]     = tmp
  end
end

pp a

1
short normal[4][4] = {{8,4,7,5},{3,4,5,7},{9,5,5,6},{3,3,3,3}};

short rotated[4][4];

for (int r = 0; r < 4; ++r)
{
  for (int c = 0; c < 4; ++c)
  {
    rotated[r][c] = normal[c][3-r];
  }
}

সাধারণ সি ++ পদ্ধতি, সেখানে বড় অ্যারেতে একটি বড় মেমরি ওভারহেড থাকবে would


এই সমস্ত উত্তরগুলির মধ্যে আমি এটি খুঁজে পেয়েছি এবং এটি পরীক্ষা করেছি যা কমপ্যাক্ট এবং ঘোরানোর জন্য যথেষ্ট
dlewin
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.