प्रत्येक सेल को मैट्रिक्स में 0 पर सेट करें यदि उस पंक्ति या कॉलम में 0 हो


152

0 और 1s के साथ एक NxN मैट्रिक्स दिया। हर पंक्ति को सेट करें जिसमें एक 0से सभी 0s हैं और हर कॉलम को सेट करें जिसमें 0सभी 0s हैं।

उदाहरण के लिए

1 0 1 1 0
0 1 1 1 0
1 1 1 1 1
1 0 1 1 1
1 1 1 1 1

का परिणाम

0 0 0 0 0
0 0 0 0 0
0 0 1 1 0
0 0 0 0 0
0 0 1 1 0

एक Microsoft इंजीनियर ने मुझे बताया कि एक समाधान है जिसमें कोई अतिरिक्त मेमोरी नहीं है, बस दो बूलियन चर और एक पास है, इसलिए मैं उस उत्तर की तलाश कर रहा हूं।

BTW, कल्पना करें कि यह थोड़ा मैट्रिक्स है, इसलिए केवल 1s और 0s मैट्रिक्स में होने की अनुमति है।


1
है ना? "जब भी आपका सामना होता है" क्या होता है? किस क्रम में आप मैट्रिक्स में तत्वों का सामना कर रहे हैं? और यदि आप सभी बिट्स का सामना करते हैं, तो क्या आपको सभी 0s वैसे भी नहीं मिलेंगे?
श्रीवत्सआर

ठीक है, जिस क्रम में आप तत्वों का सामना करने का फैसला करते हैं वह आपका निर्णय है, बात यह है कि आपको केवल उचित तत्वों को 0 सेट करना होगा। यदि आप 0 पर सेट किए गए सभी बिट्स का सामना करते हैं, तो मैट्रिक्स अभी भी शून्य से भरा होगा।
jaircazarin- पुराना-खाता

"उचित तत्व" क्या हैं? क्या आपको दो मैट्रिक्स, एक "स्रोत" मैट्रिक्स और एक "लक्ष्य" मैट्रिक्स दिया जाता है और आपको यह तय करना होगा कि "लक्ष्य" मैट्रिक्स को प्राप्त करने के लिए तत्वों का "एनकाउंटर" कैसे करें?
श्रीवत्सआर

1
मुझे लगता है कि आप '1 पास' के लिए कुछ सोचते हैं। इसे 2 पास में रैखिक रूप से किया जा सकता है, हालांकि, अतिरिक्त मेमोरी के बिना, सिर्फ 2 बूलियन ;-) इसलिए मैं दृढ़ता से मानता हूं कि इसका मतलब है कि वह इसका समाधान है (नीचे देखें)
पीरोट लेसनकी

1
यदि समस्या का वर्णन सही है, तो क्या आप कृपया अपने मित्र के साथ दोबारा जांच कर सकते हैं? मुझे लगा कि मैं हेमिंग कोड या पैरिटी बिट्स के साथ ऐसा कर सकता हूं, लेकिन अभी तक मुझे कोई सफलता नहीं मिली है, और समस्या मेरे सिर में है। :)
सीएसएल

जवाबों:


96

ठीक है, इसलिए मैं थका हुआ हूं क्योंकि यह 3 एएम है, लेकिन मेरे पास मैट्रिक्स में प्रत्येक नंबर पर ठीक 2 पास के साथ पहली कोशिश है, इसलिए ओ (एनएक्सएन) में और यह मैट्रिक्स के आकार में रैखिक है।

मैं 1rst कॉलम और पहली पंक्ति का उपयोग मार्करों के रूप में यह जानने के लिए करता हूं कि केवल 1 के साथ पंक्तियाँ / कॉल कहाँ हैं। फिर, यह याद रखने के लिए 2 चर l और c हैं कि 1rst पंक्ति / कॉलम सभी 1 के हैं। तो पहला पास मार्कर सेट करता है और बाकी को 0 पर रीसेट करता है।

दूसरा पास उन स्थानों पर 1 सेट करता है जहां पंक्तियों और कॉलनों को 1 के रूप में चिह्नित किया गया है, और एल और सी के आधार पर 1 पंक्ति / कॉल को रीसेट करता है।

मुझे दृढ़ता से संदेह है कि मुझे 1 पास में किया जा सकता है क्योंकि शुरुआत में वर्ग अंत में वर्गों पर निर्भर करते हैं। हो सकता है कि मेरा दूसरा पास अधिक कुशल बनाया जा सकता है ...

import pprint

m = [[1, 0, 1, 1, 0],
     [0, 1, 1, 1, 0],
     [1, 1, 1, 1, 1],
     [1, 0, 1, 1, 1],
     [1, 1, 1, 1, 1]]



N = len(m)

### pass 1

# 1 rst line/column
c = 1
for i in range(N):
    c &= m[i][0]

l = 1
for i in range(1,N):
    l &= m[0][i]


# other line/cols
# use line1, col1 to keep only those with 1
for i in range(1,N):
    for j in range(1,N):
        if m[i][j] == 0:
            m[0][j] = 0
            m[i][0] = 0
        else:
            m[i][j] = 0

### pass 2

# if line1 and col1 are ones: it is 1
for i in range(1,N):
    for j in range(1,N):
        if m[i][0] & m[0][j]:
            m[i][j] = 1

# 1rst row and col: reset if 0
if l == 0:
    for i in range(N):
        m [i][0] = 0

if c == 0:
    for j in range(1,N):
        m [0][j] = 0


pprint.pprint(m)

यहाँ एक समस्या यह है कि यदि n> sizeof (c) है तो यह टूट जाता है। N के सामान्य मामले में काम करने के लिए इसका विस्तार करने के लिए, आपको अपने बिट क्षेत्र को गतिशील रूप से आकार देने की आवश्यकता होगी जो मुझे लगता है कि समस्या द्वारा दिए गए अवरोध का उल्लंघन होगा।
एडम

नहीं, सी एक बिटफील्ड नहीं है, यह सिर्फ एक बूल है। & = एक बिटवाइज़ ऑप नहीं है (ठीक है, यह है, लेकिन 1-बिट वैल्यू पर), यह वहां है क्योंकि c आपको बताता है कि क्या पहला कॉलम सभी 1 (सही) है या इसमें 0 (गलत) है।
स्टीव जेसोप

2
यह विफल हो जाता है अगर शीर्ष पंक्ति [0,1,1,1 ...] मेरी बग फिक्स को एल शुरू करने के लिए m [0] [0] के बजाय 1 है
पेपरहॉर्स

वास्तव में l = 1 के लिए मैं रेंज में (1, N): l & = m [0] [i] होना चाहिए l = 1 के लिए मैं रेंज में (N): l & = m [0] [i]
क्रिस्टोफ नीरेनक

1
BTW, मेरा मानना ​​है कि दूसरी पास में स्थिति कुछ इस तरह होनी चाहिए: अगर m [i] [0] | m [०] [j]:
jaircazarin-old-account

16

यह एक पास में नहीं किया जा सकता क्योंकि किसी भी क्रम में एक बिट से पहले और बाद में बिट्स पर प्रभाव पड़ता है। IOW आप जिस भी क्रम में सरणी को पार करते हैं, आप बाद में 0 पर आ सकते हैं, जिसका अर्थ है कि आपको वापस जाना होगा और पिछले 1 को 0 में बदलना होगा।

अपडेट करें

लोगों को लगता है कि एन को कुछ निश्चित मूल्य (जैसे 8) तक सीमित करके आप इसे हल कर सकते हैं यह एक पास है। ठीक है कि एक) बिंदु और ख याद आ रही है) मूल सवाल नहीं है। मैं छँटाई पर एक प्रश्न पोस्ट नहीं करूंगा और एक उत्तर की उम्मीद करूंगा जो "आपको केवल 8 चीजों को छांटना चाहता है ..." शुरू हुआ।

उस ने कहा, यदि आप जानते हैं कि एन वास्तव में प्रतिबंधित है, तो यह एक उचित दृष्टिकोण है। ऊपर दिए गए मेरे उत्तर में मूल प्रश्न का उत्तर दिया गया है, जिसमें ऐसा कोई प्रतिबंध नहीं है।


यह अतिरिक्त मेमोरी के बिना एक पास में नहीं किया जा सकता है। यह एक पास में किया जा सकता है अगर परिणाम को स्टोर करने के लिए एक और NxN मैट्रिक्स है। इसी तरह, कुछ बिट ट्विडल और दो पास के साथ इसे अतिरिक्त मेमोरी के बिना किया जा सकता है।
paxos1977

2
आप अभी भी इसे एक पास में नहीं कर सकते हैं, भले ही आप एक अस्थायी मैट्रिक्स का उपयोग करें, या फिर कुछ अजीब है जो मुझे यहां नहीं मिल रहा है। आपको पंक्ति / स्तंभ जानकारी को कम करने के लिए एक पास की आवश्यकता है, और सब कुछ सेट करने के लिए।
लास वी। कार्लसन

मैंने इस समस्या को यह पहचान कर हल किया कि प्रति पंक्ति में केवल एक अद्वितीय गैर-शून्य मान संभव है, और इसे केवल संदर्भ द्वारा निर्दिष्ट किया गया है।
डैनियल पापासियन

@ceretullis, lassevk: मुझे अभी भी लगता है कि इसे एक पास में नहीं किया जा सकता। उस दूसरी मैट्रिक्स पर पास की गणना करनी होगी - अन्यथा आप मैट्रिक्स को केवल एक पास में कॉपी कर सकते हैं, और उस कॉपी के साथ काम कर सकते हैं जो आप चाहते थे। @ डैनियल पापासियन: आपके समाधान का कोई पैमाना नहीं है जहाँ N> #बिट्स इन इंट / लॉन्ग / जो भी हो
ड्रेमन

ड्रेमन, तकनीक ठीक है, यह सिर्फ गणित है - आप या तो हार्डवेयर का निर्माण कर सकते हैं जो यह करता है, या आप अपने शब्द आकार से बड़ी संख्या में हेरफेर करने के लिए सॉफ्टवेयर तकनीकों का उपयोग कर सकते हैं। न तो समस्या की बाधाओं का उल्लंघन करता है, IMHO
डैनियल पापासियन

10

इसलिए मेरा विचार है कि अंतिम पंक्ति / स्तंभ में मानों का उपयोग एक ध्वज के रूप में किया जाए ताकि यह इंगित किया जा सके कि संबंधित कॉलम / पंक्ति में सभी मान 1s हैं या नहीं।

संपूर्ण मैट्रिक्स के माध्यम से एक Zag Zag स्कैन का उपयोग करके अंतिम पंक्ति / कॉलम को एक्सेप्ट करें। प्रत्येक तत्व पर, आप अंतिम पंक्ति / स्तंभ में मान को वर्तमान तत्व के मान के साथ तार्किक और स्वयं के रूप में सेट करते हैं। दूसरे शब्दों में, यदि आप एक 0 से टकराते हैं, तो अंतिम पंक्ति / कॉलम 0. पर सेट हो जाएगा। यदि आप इसे 1 करते हैं, तो अंतिम पंक्ति / कॉलम में मान केवल 1 होने पर ही होगा। किसी भी स्थिति में वर्तमान तत्व को 0 पर सेट करें।

जब आप समाप्त कर लें, तो आपकी अंतिम पंक्ति / कॉलम में 1s होना चाहिए यदि संबंधित कॉलम / पंक्ति 1s से भरी हुई थी।

अंतिम पंक्ति और कॉलम के माध्यम से एक रैखिक स्कैन करें और 1s की तलाश करें। मैट्रिक्स के शरीर में संबंधित तत्वों में 1s सेट करें जहां अंतिम पंक्ति और स्तंभ दोनों 1s हैं।

कोडिंग यह ऑफ-बाय-वन एरर्स आदि से बचने के लिए मुश्किल होगा, लेकिन इसे एक पास में काम करना चाहिए।


बहुत अच्छा ... मैं उसी तर्ज पर सोच रहा था, लेकिन उस जानकारी को संग्रहीत करने के लिए अंतिम पंक्ति / कॉलम का उपयोग करने से चूक गया, इसलिए मैं Nx1 सरणियों की एक जोड़ी के लिए अतिरिक्त मेमोरी के साथ फंस गया था।
डेव शेरोहमान

1
ऐसा लगता है कि दो पास मेरे पास हैं - एक पास जिग-ज़ैग स्कैन है, दूसरा "मैट्रिक्स के शरीर में संबंधित तत्वों में सेट 1s है जहां अंतिम पंक्ति और स्तंभ दोनों 1s हैं"।
एडम रोसेनफील्ड

ज़िग-ज़ैग स्कैन (जैसा कि किसी ने मुझे बताया था कि यह कड़ाई से आवश्यक नहीं है) सभी अंतिम पंक्ति / कॉलम को ट्रेस करता है। इसलिए अंतिम / पंक्ति कॉलम को स्कैन करने से पहले स्कैन किए गए तत्वों की नकल नहीं होती है। इसलिए एक पास। दूसरे शब्दों में यह N * N मैट्रिक्स के लिए O (N ^ 2) है।
अलास्टेयर

6

मुझे यहां एक समाधान मिला है, यह एक एकल पास में चलता है, और सभी प्रसंस्करण "जगह में" करता है, जिसमें कोई अतिरिक्त मेमोरी नहीं है (स्टैक बढ़ने के लिए सहेजें)।

यह ज़ीरो के लेखन में देरी करने के लिए पुनरावृत्ति का उपयोग करता है जो निश्चित रूप से अन्य पंक्तियों और कॉल के लिए मैट्रिक्स को नष्ट कर देगा:

#include <iostream>

/**
* The idea with my algorithm is to delay the writing of zeros
* till all rows and cols can be processed. I do this using
* recursion:
* 1) Enter Recursive Function:
* 2) Check the row and col of this "corner" for zeros and store the results in bools
* 3) Send recursive function to the next corner
* 4) When the recursive function returns, use the data we stored in step 2
*       to zero the the row and col conditionally
*
* The corners I talk about are just how I ensure I hit all the row's a cols,
* I progress through the matrix from (0,0) to (1,1) to (2,2) and on to (n,n).
*
* For simplicities sake, I use ints instead of individual bits. But I never store
* anything but 0 or 1 so it's still fair ;)
*/

// ================================
// Using globals just to keep function
// call syntax as straight forward as possible
int n = 5;
int m[5][5] = {
                { 1, 0, 1, 1, 0 },
                { 0, 1, 1, 1, 0 },
                { 1, 1, 1, 1, 1 },
                { 1, 0, 1, 1, 1 },
                { 1, 1, 1, 1, 1 }
            };
// ================================

// Just declaring the function prototypes
void processMatrix();
void processCorner( int cornerIndex );
bool checkRow( int rowIndex );
bool checkCol( int colIndex );
void zeroRow( int rowIndex );
void zeroCol( int colIndex );
void printMatrix();

// This function primes the pump
void processMatrix() {
    processCorner( 0 );
}

// Step 1) This is the heart of my recursive algorithm
void processCorner( int cornerIndex ) {
    // Step 2) Do the logic processing here and store the results
    bool rowZero = checkRow( cornerIndex );
    bool colZero = checkCol( cornerIndex );

    // Step 3) Now progress through the matrix
    int nextCorner = cornerIndex + 1;
    if( nextCorner < n )
        processCorner( nextCorner );

    // Step 4) Finially apply the changes determined earlier
    if( colZero )
        zeroCol( cornerIndex );
    if( rowZero )
        zeroRow( cornerIndex );
}

// This function returns whether or not the row contains a zero
bool checkRow( int rowIndex ) {
    bool zero = false;
    for( int i=0; i<n && !zero; ++i ) {
        if( m[ rowIndex ][ i ] == 0 )
            zero = true;
    }
    return zero;
}

// This is just a helper function for zeroing a row
void zeroRow( int rowIndex ) {
    for( int i=0; i<n; ++i ) {
        m[ rowIndex ][ i ] = 0;
    }
}

// This function returns whether or not the col contains a zero
bool checkCol( int colIndex ) {
    bool zero = false;
    for( int i=0; i<n && !zero; ++i ) {
        if( m[ i ][ colIndex ] == 0 )
            zero = true;
    }

    return zero;
}

// This is just a helper function for zeroing a col
void zeroCol( int colIndex ) {
    for( int i=0; i<n; ++i ) {
        m[ i ][ colIndex ] = 0;
    }
}

// Just a helper function for printing our matrix to std::out
void printMatrix() {
    std::cout << std::endl;
    for( int y=0; y<n; ++y ) {
        for( int x=0; x<n; ++x ) {
            std::cout << m[y][x] << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

// Execute!
int main() {
    printMatrix();
    processMatrix();
    printMatrix();
}

2
अच्छा समाधान है, लेकिन आप तकनीकी रूप से दो स्वीकृत बूलियनों की तुलना में अधिक मेमोरी का उपयोग कर रहे हैं (हालांकि स्टैक पर)।
सीएसएल

1
यह> 1 पास है। यदि आप (rowIndex, i) और (i, colIndex) को प्रिंट करते हैं, क्योंकि वे checkRow और checkCol में एक्सेस होते हैं, तो आप देखेंगे कि प्रत्येक तत्व कई बार एक्सेस किया जाता है।
डेमॉन

ड्रेमन: आप सही हैं, मुझे लगता है कि हमें पहेली निर्माता से "सिंगल पास" की स्पष्ट परिभाषा चाहिए। यदि वह वास्तव में इसका मतलब है कि प्रत्येक तत्व को केवल एक बार एक्सेस किया जा सकता है, तो हमें एक अलग समाधान की आवश्यकता है।
एडम

मुझे लगता है कि मूल समस्या (जो टेलीफोन गेम के माध्यम से हमारे पास आई है) का अर्थ है कि समस्या को "जगह में" हल किया जाना चाहिए, जिसका अर्थ है कि आपके पास मैट्रिक्स की एक और प्रतिलिपि नहीं है। और अधिक इष्टतम समाधान प्रसंस्करण के लिए भंडारण की तरह अस्थायी स्वैप () की भी आवश्यकता नहीं है।
एडम

इसके अलावा, मुझे संदेह है कि बाधाओं के परिणामस्वरूप मशीन कोड का जिक्र है। मतलब, "कोड" मैंने प्रदान किया केवल 2 बूल का उपयोग करता है। मेरा संकलक क्या अनुकूलन करता है, इस पर निर्भर करते हुए, पूरी तरह से झुलसाने वाली चीज़ को इनलाइन किया जा सकता है या जो जानता है कि और क्या है। मुझे लगता है कि मेरा समाधान सही है;)
एडम

4

मुझे नहीं लगता कि यह उल्लेखनीय है। जब आप पहले वर्ग पर होते हैं और इसका मूल्य 1 होता है, तो आपके पास यह जानने का कोई तरीका नहीं होता है कि एक ही पंक्ति और स्तंभ के अन्य वर्गों के मूल्य क्या हैं। तो आपको उन लोगों की जांच करनी होगी और यदि कोई शून्य है, तो पहले वर्ग में वापस लौटें और इसके मूल्य को शून्य में बदल दें। मैं इसे दो पास में करने की सलाह दूंगा - पहला पास जानकारी इकट्ठा करता है जिसके बारे में पंक्तियों और स्तंभों को शून्य किया जाना चाहिए (जानकारी को किसी सरणी में संग्रहीत किया जाता है, इसलिए हम कुछ अतिरिक्त मेमोरी का उपयोग कर रहे हैं)। दूसरा पास मूल्यों को बदल देता है। मुझे पता है कि वह समाधान नहीं है जिसे आप खोज रहे हैं, लेकिन मुझे लगता है कि यह एक व्यावहारिक है। आपके द्वारा दी गई अड़चनें समस्या को अकारण प्रस्तुत करती हैं।


मेरे पास लगभग एक ही समाधान है (नीचे देखें) अतिरिक्त सरणियों के बिना। और यह रैखिक समय है (लेकिन 2 पास हालांकि)
पीरोट लेसनिके

@Potr: हां, दूसरा पास अपरिहार्य लगता है। मेरे द्वारा प्रस्तावित पंक्तियों और स्तंभों की जानकारी को संग्रहीत करने के लिए सरणियों का परिचय एल्गोरिथ्म को अधिक सीधे-आगे और थोड़ा तेज बनाता है क्योंकि कम जाँच और मूल्य-परिवर्तन होता है। यह भंडारण और दक्षता के बीच एक व्यापार है।
बॉयान

3

मैं इसे दो पूर्णांक चर और दो पास (32 पंक्तियों और स्तंभों के साथ कर सकता हूं ...)

bool matrix[5][5] = 
{ 
    {1, 0, 1, 1, 0},
    {0, 1, 1, 1, 0},
    {1, 1, 1, 1, 1},
    {1, 0, 1, 1, 1},
    {1, 1, 1, 1, 1}
};

int CompleteRows = ~0;
int CompleteCols = ~0;

// Find the first 0
for (int row = 0; row < 5; ++row)
{
    for (int col = 0; col < 5; ++col)
    {
        CompleteRows &= ~(!matrix[row][col] << row);
        CompleteCols &= ~(!matrix[row][col] << col);
    }
}

for (int row = 0; row < 5; ++row)
    for (int col = 0; col < 5; ++col)
        matrix[row][col] = (CompleteRows & (1 << row)) && (CompleteCols & (1 << col));

क्या यह C # है? ~ का क्या अर्थ है?
स्केयर

यह C ++ है। ~एक चर में सभी बिट्स inverts। 0x00000000 0x00000000 बन जाता है। मैं मूल रूप से सभी लोगों के साथ शुरू करता हूं, और एक पंक्ति / कॉलम के लिए बिट को साफ करता हूं जब मुझे पता चलता है कि 0. कंप्लीकोल्स में बिट्स 2 और 3 सेट हैं, और कम्प्लीटर्स में बिट्स 2 और 4 सेट (0 आधारित) हैं।
ग्रहण

तब आप बिट्स को पूरी तरह से दोनों पूर्णकों और कंप्रेशर्स में मैट्रिक्स के अनुसार सेट करते हैं।
ग्रहण

3

समस्या को एक पास में हल किया जा सकता है

आई एक्स जे सरणी में मैट्रिक्स को सहेजना।

1 0 1 1 0
0 1 1 1 0
1 1 1 1 1
1 0 1 1 1 
1 1 1 1 1

one each pass save the values of i and j for an element which is 0 in arrays a and b
when first row is scanned a= 1 b = 2,5
when second row is scanned a=1,2 b= 1,2,5
when third row is scanned no change
when fourth row is scanned a= 1,2,4 and b= 1,2,5
when fifth row is scanned no change .

अब सभी मानों को I और j के मानों के लिए 0 में प्रिंट करें और शेष मूल्यों में 1 (3,3) (3,4) (5,3) और (5,4) शेष हैं।


1

एक अन्य समाधान जो दो पास लेता है, वह है क्षैतिज और लंबवत रूप से ANDs को संचित करना:

1 0 1 1 0 | 0
0 1 1 1 0 | 0
1 1 1 1 1 | 1
1 0 1 1 1 | 0
1 1 1 1 1 | 1
----------+
0 0 1 1 0    

मैंने सोचा कि मैं समता बिट्स , हैमिंग कोड या डायनामिक प्रोग्रामिंग का उपयोग करके इस तरह के एक एल्गोरिथ्म को डिजाइन कर सकता हूं , संभवतः उन दो बूलियनों को 2-बिट संख्या के रूप में उपयोग कर रहा हूं, लेकिन मुझे अभी तक कोई सफलता नहीं मिली है।

क्या आप कृपया अपने इंजीनियर के साथ समस्या कथन की फिर से जाँच कर सकते हैं और हमें बता सकते हैं? अगर वहाँ है वास्तव में एक समाधान है, मैं इस समस्या पर दूर छिल रखना चाहते हैं।


1

सभी पंक्तियों और साथ में क्या है का ट्रैक रखने के लिए एक एकल चर रखें।

यदि एक पंक्ति -1 (सभी 1s) है, तो अगली पंक्ति को उस चर के संदर्भ में बनाएं

यदि एक पंक्ति कुछ भी है लेकिन, यह 0. है तो आप एक पास में सब कुछ कर सकते हैं। छद्म-कोड:

foreach (my $row) rows {
     $andproduct = $andproduct & $row;
     if($row != -1) {
        zero out the row
     }  else {
        replace row with a reference to andproduct
     }
}

यह करना चाहिए, एक ही पास में - लेकिन यहाँ एक धारणा है कि N एक पंक्ति में CPU के लिए अंकगणित करने के लिए पर्याप्त छोटा है, अन्यथा आपको यह निर्धारित करने के लिए प्रत्येक पंक्ति पर लूप करने की आवश्यकता है कि क्या यह सब है 1s या नहीं, मुझे विश्वास है। लेकिन यह देखते हुए कि आप अल्गोस के बारे में पूछ रहे हैं और मेरे हार्डवेयर को बाधित नहीं कर रहे हैं, मैं बस अपना उत्तर "बिल्ड सीपीयू बनाएँ जो एन-बिट अंकगणितीय ..." का समर्थन करता है

यहाँ एक उदाहरण है कि यह कैसे किया जा सकता है। सी। नोट I में तर्क दिया गया है कि मान और गिरफ्तारी सरणी को दर्शाते हैं, और p और numproduct मेरी पुनरावृत्ति हैं और उत्पाद चर का उपयोग समस्या को लागू करने के लिए करते हैं। (मैं अपने काम को मान्य करने के लिए सूचक अंकगणित के साथ गिरफ्तारी पर काबू पा सकता था, लेकिन एक बार पर्याप्त था!)

int main() {
    int values[] = { -10, 14, -1, -9, -1 }; /* From the problem spec, converted to decimal for my sanity */
    int *arr[5] = { values, values+1, values+2, values+3, values+4 };
    int **p;
    int numproduct = 127;

    for(p = arr; p < arr+5; ++p) {
        numproduct = numproduct & **p;
        if(**p != -1) {
            **p = 0;
        } else {
            *p = &numproduct;
        }
    }

    /* Print our array, this loop is just for show */
    int i;
    for(i = 0; i < 5; ++i) {
        printf("%x\n",*arr[i]);
    }
    return 0;
}

यह 0, 0, 6, 0, 6 पैदा करता है, जो दिए गए इनपुट के लिए परिणाम है।

या PHP में, अगर लोगों को लगता है कि C में मेरे स्टैक गेम धोखा दे रहे हैं (मैं आपको सुझाव देता हूं कि यह नहीं है, क्योंकि मुझे मैट्रिक्स को जिस भी तरीके से स्टोर करना चाहिए, कृपया):

<?php

$values = array(-10, 14, -1, -9, -1);
$numproduct = 127;

for($i = 0; $i < 5; ++$i) {
    $numproduct = $numproduct & $values[$i];
    if($values[$i] != -1) {
        $values[$i] = 0;
    } else {
        $values[$i] = &$numproduct;
    }
}

print_r($values);

क्या मैं कुछ भूल रहा हूँ?


यह काम नहीं करता है यदि N एक int / long / बिट्स में बिट्स की संख्या से बड़ा है, तो जो मुझे नहीं लगता कि यह मायने रखता है।
ड्रेमन डेसी

अगर यह 0 के एरे के निचले भाग पर है (इसे मूल्यों के साथ आज़माएँ [] = {-1, -9, -1, 14, -10}), तो यह चीज़ों को पकड़ नहीं पाएगा।
ग्रहण

ड्रेमन, मैं अपने उत्तर में निर्दिष्ट करता हूं कि हार्डवेयर के बिना प्रश्न के हिस्से के रूप में, आप "एक सीपीयू का निर्माण करें जो एन-बिट अंकगणित का समर्थन करता है।"
डैनियल पापासियन

जोश, मैं पालन नहीं करते। सी या पीएचपी समाधान और आपके द्वारा सुझाए गए सरणी के साथ, मुझे 6 0 6 0 0 मिलता है, जो मुझे लगता है कि सही उत्तर है।
डैनियल पापासियन

@ डैनियल - आप नहीं कर सकते, क्योंकि एन एक स्थिर नहीं है। इसके अलावा "1Mbit शब्दों के साथ एक नया कंप्यूटर बनाने के लिए शायद ही एक उचित एल्गोरिदमिक कदम है।
डेमन डे

1

अच्छा चल निकला। यह समाधान स्टैक पर बनाए गए सिर्फ दो बूलियन का उपयोग करता है, लेकिन फंक्शन रिकर्सिव होने के बाद से स्टैक पर कई बार बूलियन बनाए जाते हैं।

typedef unsigned short     WORD;
typedef unsigned char      BOOL;
#define true  1
#define false 0
BYTE buffer[5][5] = {
1, 0, 1, 1, 0,
0, 1, 1, 1, 0,
1, 1, 1, 1, 1,
1, 0, 1, 1, 1,
1, 1, 1, 1, 1
};
int scan_to_end(BOOL *h,BOOL *w,WORD N,WORD pos_N)
{
    WORD i;
    for(i=0;i<N;i++)
    {
        if(!buffer[i][pos_N])
            *h=false;
        if(!buffer[pos_N][i])
            *w=false;
    }
    return 0;
}
int set_line(BOOL h,BOOL w,WORD N,WORD pos_N)
{
    WORD i;
    if(!h)
        for(i=0;i<N;i++)
            buffer[i][pos_N] = false;
    if(!w)
        for(i=0;i<N;i++)
            buffer[pos_N][i] = false;
    return 0;
}
int scan(int N,int pos_N)
{
    BOOL h = true;
    BOOL w = true;
    if(pos_N == N)
        return 0;
    // Do single scan
    scan_to_end(&h,&w,N,pos_N);
    // Scan all recursive before changeing data
    scan(N,pos_N+1);
    // Set the result of the scan
    set_line(h,w,N,pos_N);
    return 0;
}
int main(void)
{
    printf("Old matrix\n");
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[0][0],(WORD)buffer[0][1],(WORD)buffer[0][2],(WORD)buffer[0][3],(WORD)buffer[0][4]);
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[1][0],(WORD)buffer[1][1],(WORD)buffer[1][2],(WORD)buffer[1][3],(WORD)buffer[1][4]);
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[2][0],(WORD)buffer[2][1],(WORD)buffer[2][2],(WORD)buffer[2][3],(WORD)buffer[2][4]);
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[3][0],(WORD)buffer[3][1],(WORD)buffer[3][2],(WORD)buffer[3][3],(WORD)buffer[3][4]);
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[4][0],(WORD)buffer[4][1],(WORD)buffer[4][2],(WORD)buffer[4][3],(WORD)buffer[4][4]);
    scan(5,0);
    printf("New matrix\n");
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[0][0],(WORD)buffer[0][1],(WORD)buffer[0][2],(WORD)buffer[0][3],(WORD)buffer[0][4]);
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[1][0],(WORD)buffer[1][1],(WORD)buffer[1][2],(WORD)buffer[1][3],(WORD)buffer[1][4]);
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[2][0],(WORD)buffer[2][1],(WORD)buffer[2][2],(WORD)buffer[2][3],(WORD)buffer[2][4]);
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[3][0],(WORD)buffer[3][1],(WORD)buffer[3][2],(WORD)buffer[3][3],(WORD)buffer[3][4]);
    printf( "%d,%d,%d,%d,%d \n", (WORD)buffer[4][0],(WORD)buffer[4][1],(WORD)buffer[4][2],(WORD)buffer[4][3],(WORD)buffer[4][4]);
    system( "pause" );
    return 0;
}

यह एक पैटर्न में स्कैन करता है जैसे:

s,s,s,s,s
s,0,0,0,0
s,0,0,0,0
s,0,0,0,0
s,0,0,0,0


0,s,0,0,0
s,s,s,s,s
0,s,0,0,0
0,s,0,0,0
0,s,0,0,0

और इसी तरह

और फिर स्कैन कार्यों में से प्रत्येक पर रिटर्न पर इस पैटर्न में मूल्यों को बदलना। (नीचे से ऊपर):

0,0,0,0,c
0,0,0,0,c
0,0,0,0,c
0,0,0,0,c
c,c,c,c,c


0,0,0,c,0
0,0,0,c,0
0,0,0,c,0
c,c,c,c,c
0,0,0,c,0

और इसी तरह


मुझे लगता है कि यह सही नहीं है, क्योंकि आप अभी भी अपने ढेर पर दो से अधिक बुलियन का उपयोग करते हैं।
सीएसएल

के रूप में मैं दो बूलियन की उदास तरह। यह मेरे द्वारा दिए गए चश्मे के बारे में सोच सकता है। मैं यहां एक वास्तविक समाधान देखना पसंद करूंगा। यदि यह संभव है।
eaanon01

मुझे नहीं लगता कि आवश्यकताएं स्टैक बढ़ने की बात कर रही हैं। मुझे लगता है कि यह पूरी तरह से वैध समाधान है।
एडम

यही मेरा तू भी है। लेकिन मुझे यकीन है कि जब तक कोई और एक बेहतर समाधान पोस्ट नहीं करेगा। कम से कम मेरा समाधान अनिवार्य है और किसी के द्वारा भी सत्यापित किया जा सकता है। :) ... मैं व्यावहारिक समस्याओं के लिए psudo कोड के लिए नहीं हूँ। Thnx
eaanon01

1

ठीक है यह एक समाधान है

  • काम भंडारण के लिए सिर्फ एक अतिरिक्त लंबे मूल्य का उपयोग करता है।
  • कोई पुनरावृत्ति का उपयोग करता है।
  • केवल एन का एक पास, एन * एन भी नहीं।
  • एन के अन्य मूल्यों के लिए काम करेगा लेकिन नए #defines की आवश्यकता होगी।
#include <stdio.h>
#define BIT30 (1<<24)
#define COLMASK 0x108421L
#define ROWMASK 0x1fL
unsigned long long STARTGRID = 
((0x10 | 0x0 | 0x4 | 0x2 | 0x0) << 20) |
((0x00 | 0x8 | 0x4 | 0x2 | 0x0) << 15) |
((0x10 | 0x8 | 0x4 | 0x2 | 0x1) << 10) |
((0x10 | 0x0 | 0x4 | 0x2 | 0x1) << 5) |
((0x10 | 0x8 | 0x4 | 0x2 | 0x1) << 0);


void dumpGrid (char* comment, unsigned long long theGrid) {
    char buffer[1000];
    buffer[0]='\0';
    printf ("\n\n%s\n",comment);
    for (int j=1;j<31; j++) {
        if (j%5!=1)
            printf( "%s%s", ((theGrid & BIT30)==BIT30)? "1" : "0",(((j%5)==0)?"\n" : ",") );    
        theGrid = theGrid << 1;
    }
}

int main (int argc, const char * argv[]) {
    unsigned long long rowgrid = STARTGRID;
    unsigned long long colGrid = rowgrid;

    unsigned long long rowmask = ROWMASK;
    unsigned long long colmask = COLMASK;

    dumpGrid("Initial Grid", rowgrid);
    for (int i=0; i<5; i++) {
        if ((rowgrid & rowmask)== rowmask) rowgrid |= rowmask;
        else rowgrid &= ~rowmask;
        if ((colGrid & colmask) == colmask) colmask |= colmask;
        else colGrid &=  ~colmask;
        rowmask <<= 5;
        colmask <<= 1;
    }
    colGrid &= rowgrid;
    dumpGrid("RESULT Grid", colGrid);
    return 0;
    }

यह सुनिश्चित करने के लिए एक अच्छा समाधान है। और मुझे लगता है कि हर एक समाधान यहाँ आवश्यकताओं की कम से कम उपेक्षा करता है। तो एन के लिए अधिकतम अनुमत मूल्य के साथ एक समाधान होना दुनिया की सबसे बुरी बात नहीं है, इसलिए इस पर अच्छा काम :)
एडम

N से 8 को प्रतिबंधित करना और यह दावा करना कि एक पास की आवश्यकता केवल सादे गूंगा है। यह एक सामान्य समाधान नहीं है। प्रश्न में एन के आकार का कोई प्रतिबंध नहीं बताया गया था, इसलिए आपने केवल एक उप-समस्या को हल किया है।
डेमॉन

लेकिन इन सभी समाधानों में एक या दूसरे तरीके से एन की सीमा होती है।
एंथनी लैंबर्ट

यह कहते हुए कि यह एन का एक पास है, स्पष्ट रूप से पूरी तरह से गलत है। यहां तक ​​कि मूल मैट्रिक्स में प्रत्येक स्थिति का मूल्य पढ़ना ओ (एन ^ 2) है और समाधान की गणना करने में सक्षम होने के लिए कम से कम एक बार प्रत्येक स्थिति में मूल्य को पढ़ना सबसे आवश्यक है। यहां तक ​​कि अगर आप एक लंबे समय के भीतर एकल बिट्स के रूप में मूल्यों को संग्रहीत करते हैं, तो प्रत्येक बिट तक पहुंच O (N ^ 2) होने वाली है क्योंकि O (N ^ 2) बिट्स हैं।
एगोरथ

यह स्पष्ट रूप से एक है RowGrid मान को पूरा ग्रिड संग्रहीत करता है और पहली बार पढ़ने के बाद यदि कोई भी अच्छा हो तो अनुकूलक पूरे एल्गोरिथम के लिए प्रोसेसर रजिस्टर में से एक होगा।
एंथनी लैंबर्ट

1

वास्तव में। यदि आप बस एल्गोरिथ्म को चलाना चाहते हैं और परिणाम प्रिंट करना चाहते हैं (अर्थात उन्हें पुनर्स्थापित नहीं करते हैं, तो यह आसानी से एक पास में किया जा सकता है। मुसीबत तब आती है जब आप एल्गोरिथ्म चलाने के दौरान सरणी को संशोधित करने का प्रयास करते हैं।

यहाँ मेरा समाधान है इसमें सिर्फ एक (i, j) तत्व के लिए पंक्तियों / स्तंभ मानों को शामिल करना और इसे प्रिंट करना शामिल है।

#include <iostream>
#include "stdlib.h"

void process();

int dim = 5;
bool m[5][5]{{1,0,1,1,1},{0,1,1,0,1},{1,1,1,1,1},{1,1,1,1,1},{0,0,1,1,1}};


int main() {
    process();
    return 0;
}

void process() {
    for(int j = 0; j < dim; j++) {
        for(int i = 0; i < dim; i++) {
            std::cout << (
                          (m[0][j] & m[1][j] & m[2][j] & m[3][j] & m[4][j]) &
                          (m[i][0] & m[i][1] & m[i][2] & m[i][3] & m[i][4])
                          );
        }
        std::cout << std::endl;
    }
}

1

मैंने C # में इस समस्या को हल करने की कोशिश की।

मैंने वास्तविक मैट्रिक्स से अलग दो लूप वैरिएबल (i और j) का उपयोग किया है और n इसके आयाम का प्रतिनिधित्व करता है

तर्क मैंने कोशिश की है:

  1. गणना करें और मैट्रिक्स के प्रत्येक संकेंद्रित वर्ग में शामिल पंक्तियों और कॉलनों के लिए
  2. इसे अपने कोने की कोशिकाओं में संग्रहीत करें (मैंने उन्हें एंटी-क्लॉकवाइज ऑर्डर में संग्रहीत किया है)
  3. किसी विशेष वर्ग का मूल्यांकन करते समय दो कोनों के मूल्यों को बनाए रखने के लिए दो बूल चर का उपयोग किया जाता है।
  4. बाहरी लूप (i) मध्य मार्ग होने पर यह प्रक्रिया समाप्त हो जाएगी।
  5. कोने की कोशिकाओं (बाकी के लिए) के आधार पर अन्य कोशिकाओं के परिणामों का मूल्यांकन करें। इस प्रक्रिया के दौरान कोने की कोशिकाओं को छोड़ दें।
  6. जब मैं n पर पहुंचता हूं, तो सभी कोशिकाओं के कोने की कोशिकाओं को छोड़कर इसका परिणाम होगा।
  7. कोने की कोशिकाओं को अपडेट करें। यह समस्या में उल्लिखित सिंगल पास बाधा की तुलना में n / 2 की लंबाई के लिए एक अतिरिक्त पुनरावृत्ति है।

कोड:

void Evaluate(bool [,] matrix, int n)
{
    bool tempvar1, tempvar2;

    for (var i = 0; i < n; i++)
    {
        tempvar1 = matrix[i, i];
        tempvar2 = matrix[n - i - 1, n - i - 1];

        var j = 0;

        for (j = 0; j < n; j++)
        {
            if ((i < n/2) || (((n % 2) == 1) && (i == n/2) && (j <= i)))
            {
                // store the row and col & results in corner cells of concentric squares
                tempvar1 &= matrix[j, i];
                matrix[i, i] &= matrix[i, j];
                tempvar2 &= matrix[n - j - 1, n - i - 1];
                matrix[n - i - 1, n - i - 1] &= matrix[n - i - 1, n - j - 1];
            }
            else
            {
                // skip corner cells of concentric squares
                if ((j == i) || (j == n - i - 1)) continue;

                // calculate the & values for rest of them
                matrix[i, j] = matrix[i, i] & matrix[n - j - 1, j];
                matrix[n - i - 1, j] = matrix[n - i - 1, n - i - 1] & matrix[n - j - 1, j];

                if ((i == n/2) && ((n % 2) == 1))
                {
                    // if n is odd
                    matrix[i, n - j - 1] = matrix[i, i] & matrix[j, n - j - 1];
                }
            }
        }

        if ((i < n/2) || (((n % 2) == 1) && (i <= n/2)))
        {
            // transfer the values from temp variables to appropriate corner cells of its corresponding square
            matrix[n - i - 1, i] = tempvar1;
            matrix[i, n - i - 1] = tempvar2;
        }
        else if (i == n - 1)
        {
            // update the values of corner cells of each concentric square
            for (j = n/2; j < n; j++)
            {
                tempvar1 = matrix[j, j];
                tempvar2 = matrix[n - j - 1, n - j - 1];

                matrix[j, j] &= matrix[n - j - 1, j];
                matrix[n - j - 1, j] &= tempvar2;

                matrix[n - j - 1, n - j - 1] &= matrix[j, n - j - 1];
                matrix[j, n - j - 1] &= tempvar1;
            }
        }
    }
}

1

एक पास - मैंने केवल एक बार इनपुट का पता लगाया है लेकिन एक नए सरणी और केवल दो अतिरिक्त बूलियन चर का उपयोग किया है।

public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.nextLine();

        boolean rowDel = false, colDel = false;
        int arr[][] = new int[n][n];
        int res[][] = new int[n][n];
        int i, j;
        for (i = 0; i < n; i++) {

            for (j = 0; j < n; j++) {
                arr[i][j] = sc.nextInt();
                res[i][j] = arr[i][j];  
            }
        }

        for (i = 0; i < n; i++) {

            for (j = 0; j < n; j++) {
                if (arr[i][j] == 0)
                    colDel = rowDel = true; //See if we have to delete the
                                            //current row and column
                if (rowDel == true){
                    res[i] = new int[n];
                    rowDel = false;
                }
                if(colDel == true){
                    for (int k = 0; k < n; k++) {
                        res[k][j] = 0;
                    }
                    colDel = false;
                }

            }

        }

        for (i = 0; i < n; i++) {

            for (j = 0; j < n; j++) {
                System.out.print(res[i][j]);
            }
            System.out.println();
        }
        sc.close();

    }

0

असंभव को देखते हुए बाधाओं को देखते हुए, इसे ओवरलैपिंग, बारी-बारी से पंक्ति / स्तंभ फैशन में मैट्रिक्स को ट्रेस करके, जो कि ज़िग-ज़ैग फैशन में ईंटों को बिछाने के समान एक पैटर्न बना देगा, के लिए सबसे अधिक अंतरिक्ष कुशल तरीका है:

-----
|----
||---
|||--
||||-

इसका उपयोग करते हुए, आप प्रत्येक पंक्ति / कॉलम में जाएंगे, जैसा कि संकेत दिया गया है, और यदि आप किसी भी समय 0 का सामना करते हैं, तो बूलियन चर सेट करें, और उस पंक्ति / कॉलम को फिर से चलाएं, प्रविष्टियों को 0 पर सेट करें जैसा कि आप जाते हैं।

इसके लिए अतिरिक्त मेमोरी की आवश्यकता नहीं होगी, और केवल एक बूलियन चर का उपयोग किया जाएगा। दुर्भाग्य से, अगर "दूर" बढ़त सभी के लिए 0 पर सेट है, तो यह सबसे खराब स्थिति है और आप पूरे सरणी को दो बार चलते हैं।


मैं गलत हो सकता है, लेकिन क्या आपको यकीन है कि यह काम करता है? जब आप 3rd कॉलम कर रहे हों, तो कहिए, आपको कैसे पता चलेगा कि पहली पंक्ति में, इसके शीर्ष पर मान 1 पंक्ति या 1 था, क्या आपने पहली पंक्ति संसाधित की थी?
स्टीव जेसोप

तुम्हें पता नहीं है, लेकिन तुम भी जरूरत नहीं है यदि यह 0 था, तो पूरे कॉलम को 0. होना चाहिए। यदि पिछली पंक्ति का मान 1 है, तो आप जानते हैं कि इसके ऊपर की सभी पंक्तियाँ 1 हैं (और हमेशा रही हैं)।
डेव शेरोहमान

0

परिणाम मैट्रिक्स बनाएं और सभी मानों को 1 पर सेट करें। 0 के सामने आते ही डेटा मैट्रिक्स से गुजरें, परिणाम मैट्रिक्स पंक्ति कॉलम को 0 पर सेट करें

पहले पास के अंत में, परिणाम मैट्रिक्स का सही उत्तर होगा।

देखने में काफी साधारण लगता है। क्या कोई चाल है जो मुझे याद आ रही है? क्या आपको परिणाम सेट का उपयोग करने की अनुमति नहीं है?

संपादित करें:

एक F # फ़ंक्शन की तरह दिखता है, लेकिन यह तब से थोड़ा धोखा दे रहा है जब आप एक पास कर रहे हैं, तो फ़ंक्शन पुनरावर्ती हो सकता है।

ऐसा लगता है कि साक्षात्कारकर्ता यह पता लगाने की कोशिश कर रहा है कि क्या आप कार्यात्मक प्रोग्रामिंग जानते हैं।


1
एक परिणाम सेट का उपयोग अतिरिक्त मेमोरी ले रहा होगा।
cdeszaq

कार्यात्मक प्रोग्रामिंग मूल सरणी को जगह में संशोधित नहीं करेगी।
Svante

0

ठीक है, मैं 4 बूल और 2 लूप काउंटर का उपयोग करके एकल-पास, इन-प्लेस (गैर-पुनरावर्ती) समाधान के साथ आया था। मैंने इसे 2 बूल और 2 इनट्स तक कम करने में कामयाब नहीं किया है, लेकिन अगर यह संभव था तो मुझे आश्चर्य नहीं होगा। यह प्रत्येक कोशिका के लगभग 3 पढ़ता है और 3 लिखता है, और यह O (N ^ 2) होना चाहिए। सरणी आकार में रैखिक।

मुझे इस एक पहेली को सुलझाने में कुछ घंटों का समय लगा - मैं एक साक्षात्कार के दबाव में इसके साथ नहीं आना चाहता! अगर मैंने एक उल्लू बनाया है तो मैं इसे देख कर बहुत थक गया हूँ ...

उम ... मैं "सिंगल-पास" को एक बार प्रत्येक मूल्य को छूने के बजाय मैट्रिक्स के माध्यम से एक स्वीप बनाने के रूप में परिभाषित करना चुन रहा हूं! :-)

#include <stdio.h>
#include <memory.h>

#define SIZE    5

typedef unsigned char u8;

u8 g_Array[ SIZE ][ SIZE ];

void Dump()
{
    for ( int nRow = 0; nRow < SIZE; ++nRow )
    {
        for ( int nColumn = 0; nColumn < SIZE; ++nColumn )
        {
            printf( "%d ", g_Array[ nRow ][ nColumn ] );
        }
        printf( "\n" );
    }
}

void Process()
{
    u8 fCarriedAlpha = true;
    u8 fCarriedBeta = true;
    for ( int nStep = 0; nStep < SIZE; ++nStep )
    {
        u8 fAlpha = (nStep > 0) ? g_Array[ nStep-1 ][ nStep ] : true;
        u8 fBeta = (nStep > 0) ? g_Array[ nStep ][ nStep - 1 ] : true;
        fAlpha &= g_Array[ nStep ][ nStep ];
        fBeta &= g_Array[ nStep ][ nStep ];
        g_Array[ nStep-1 ][ nStep ] = fCarriedBeta;
        g_Array[ nStep ][ nStep-1 ] = fCarriedAlpha;
        for ( int nScan = nStep + 1; nScan < SIZE; ++nScan )
        {
            fBeta &= g_Array[ nStep ][ nScan ];
            if ( nStep > 0 )
            {
                g_Array[ nStep ][ nScan ] &= g_Array[ nStep-1 ][ nScan ];
                g_Array[ nStep-1][ nScan ] = fCarriedBeta;
            }

            fAlpha &= g_Array[ nScan ][ nStep ];
            if ( nStep > 0 )
            {
                g_Array[ nScan ][ nStep ] &= g_Array[ nScan ][ nStep-1 ];
                g_Array[ nScan ][ nStep-1] = fCarriedAlpha;
            }
        }

        g_Array[ nStep ][ nStep ] = fAlpha & fBeta;

        for ( int nScan = nStep - 1; nScan >= 0; --nScan )
        {
            g_Array[ nScan ][ nStep ] &= fAlpha;
            g_Array[ nStep ][ nScan ] &= fBeta;
        }
        fCarriedAlpha = fAlpha;
        fCarriedBeta = fBeta;
    }
}

int main()
{
    memset( g_Array, 1, sizeof(g_Array) );
    g_Array[0][1] = 0;
    g_Array[0][4] = 0;
    g_Array[1][0] = 0;
    g_Array[1][4] = 0;
    g_Array[3][1] = 0;

    printf( "Input:\n" );
    Dump();
    Process();
    printf( "\nOutput:\n" );
    Dump();

    return 0;
}

0

मुझे आशा है कि आप मेरे 1-पास c # समाधान का आनंद लेंगे

आप O (1) के साथ एक तत्व को पुनः प्राप्त कर सकते हैं और केवल एक पंक्ति और मैट्रिक्स के एक स्तंभ के स्थान की आवश्यकता होती है

bool[][] matrix =
{
    new[] { true, false, true, true, false }, // 10110
    new[] { false, true, true, true, false }, // 01110
    new[] { true, true, true, true, true },   // 11111
    new[] { true, false, true, true, true },  // 10111
    new[] { true, true, true, true, true }    // 11111
};

int n = matrix.Length;
bool[] enabledRows = new bool[n];
bool[] enabledColumns = new bool[n];

for (int i = 0; i < n; i++)
{
    enabledRows[i] = true;
    enabledColumns[i] = true;
}

for (int rowIndex = 0; rowIndex < n; rowIndex++)
{
    for (int columnIndex = 0; columnIndex < n; columnIndex++)
    {
        bool element = matrix[rowIndex][columnIndex];
        enabledRows[rowIndex] &= element;
        enabledColumns[columnIndex] &= element;
    }
}

for (int rowIndex = 0; rowIndex < n; rowIndex++)
{
    for (int columnIndex = 0; columnIndex < n; columnIndex++)
    {
        bool element = enabledRows[rowIndex] & enabledColumns[columnIndex];
        Console.Write(Convert.ToInt32(element));
    }
    Console.WriteLine();
}

/*
    00000
    00000
    00110
    00000
    00110
*/

मुझे लगता है कि एकमात्र मुद्दा यह हो सकता है कि आप इस कार्य को करने के लिए दो अतिरिक्त सरणियों का उपयोग कर रहे हैं। स्टीप्युलेशन में से एक अतिरिक्त मेमोरी का उपयोग नहीं करना है। लेकिन हालांकि अच्छा है! यह मूल रूप से मैंने अपने उत्तर में क्या किया :)
केनी कासन

0

1 पास, 2 बुलियन। मुझे सिर्फ पुनरावृत्तियों में पूर्णांक अनुक्रमणिकाओं को गिनना नहीं है।

यह पूर्ण समाधान नहीं है, लेकिन मैं इस बिंदु को पास नहीं कर सकता।

अगर मैं केवल यह निर्धारित कर सकता था कि 0 एक मूल 0 है या 1 जो कि 0 में परिवर्तित हो गया है तो मुझे -1 का उपयोग नहीं करना पड़ेगा और यह काम करेगा।

मेरा आउटपुट इस तरह है:

-1  0 -1 -1  0
 0 -1 -1 -1  0
-1 -1  1  1 -1
-1  0 -1 -1 -1
-1 -1  1  1 -1

मेरे दृष्टिकोण की मौलिकता एक पंक्ति या स्तंभ की परीक्षा के पहले आधे हिस्से का उपयोग करके यह निर्धारित करने के लिए है कि इसमें मान सेट करने के लिए 0 और अंतिम आधा है - यह x और चौड़ाई-x और फिर y और ऊंचाई को देखते हुए किया जाता है -वह प्रत्येक पुनरावृत्ति में। पुनरावृत्ति के पहले छमाही के परिणामों के आधार पर, यदि पंक्ति या स्तंभ में 0 पाया गया था, तो मैं 1 के -1 को बदलने के लिए पुनरावृत्ति के अंतिम आधे भाग का उपयोग करता हूं।

मुझे बस एहसास हुआ कि यह केवल 1 बूलियन के साथ किया जा सकता है 1 से ...?

मैं यह उम्मीद करते हुए पोस्ट कर रहा हूं कि कोई व्यक्ति यह कह सकता है, "आह, बस यह करो ..." (और मैंने इसे पोस्ट न करने के लिए बहुत समय बिताया।)

यहाँ VB में कोड है:

Dim D(,) As Integer = {{1, 0, 1, 1, 1}, {0, 1, 1, 0, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {0, 0, 1, 1, 1}}

Dim B1, B2 As Boolean

For y As Integer = 0 To UBound(D)

    B1 = True : B2 = True

    For x As Integer = 0 To UBound(D)

        // Scan row for 0's at x and width - x positions. Halfway through I'll konw if there's a 0 in this row.
        //If a 0 is found set my first boolean to false.
        If x <= (Math.Ceiling((UBound(D) + 1) / 2) - 1) Then
            If D(x, y) = 0 Or D(UBound(D) - x, y) = 0 Then B1 = False
        End If

        //If the boolean is false then a 0 in this row was found. Spend the last half of this loop
        //updating the values. This is where I'm stuck. If I change a 1 to a 0 it will cause the column
        //scan to fail. So for now I change to a -1. If there was a way to change to 0 yet later tell if
        //the value had changed this would work.
        If Not B1 Then
            If x >= (Math.Ceiling((UBound(D) + 1) / 2) - 1) Then
                If D(x, y) = 1 Then D(x, y) = -1
                If D(UBound(D) - x, y) = 1 Then D(UBound(D) - x, y) = -1
            End If
        End If

        //These 2 block do the same as the first 2 blocks but I switch x and y to do the column.
        If x <= (Math.Ceiling((UBound(D) + 1) / 2) - 1) Then
            If D(y, x) = 0 Or D(y, UBound(D) - x) = 0 Then B2 = False
        End If

        If Not B2 Then
            If x >= (Math.Ceiling((UBound(D) + 1) / 2) - 1) Then
                If D(y, x) = 1 Then D(y, x) = -1
                If D(y, UBound(D) - x) = 1 Then D(y, UBound(D) - x) = -1
            End If
        End If

    Next
Next

0

कोई भी द्विआधारी रूपों का उपयोग नहीं कर रहा है? चूंकि यह केवल 1 और 0 है। हम बाइनरी वैक्टर का उपयोग कर सकते हैं।

def set1(M, N):
    '''Set 1/0s on M according to the rules.

    M is a list of N integers. Each integer represents a binary array, e.g.,
    000100'''
    ruler = 2**N-1
    for i,v in enumerate(M):
        ruler = ruler & M[i]
        M[i] = M[i] if M[i]==2**N-1 else 0  # set i-th row to all-0 if not all-1s
    for i,v in enumerate(M):
        if M[i]: M[i] = ruler
    return M

यहाँ परीक्षण है:

M = [ 0b10110,
      0b01110,
      0b11111,
      0b10111,
      0b11111 ]

print "Before..."
for i in M: print "{:0=5b}".format(i)

M = set1(M, len(M))
print "After..."
for i in M: print "{:0=5b}".format(i)

और आउटपुट:

Before...
10110
01110
11111
10111
11111
After...
00000
00000
00110
00000
00110

0

एक पास का उपयोग करने के लिए आप कुछ ऐसा कर सकते हैं लेकिन इनपुट और आउटपुट मैट्रिक्स:

output(x,y) = col(xy) & row(xy) == 2^n

col(xy)बिंदु वाले कॉलम में बिट्स कहां है xy; row(xy)बिंदु वाली पंक्ति में बिट्स है xynमैट्रिक्स का आकार है।

फिर इनपुट पर बस लूप करें। संभवतः अधिक स्थान कुशल होने के लिए विस्तार योग्य है?


0

एक मैट्रिक्स स्कैन, दो बूलियन, कोई पुनरावृत्ति नहीं।

दूसरे पास से कैसे बचें? जब उनके छोर पर शून्य दिखाई देता है, तो पंक्तियों या स्तंभों को खाली करने के लिए दूसरे पास की आवश्यकता होती है।

हालाँकि इस समस्या को हल किया जा सकता है, क्योंकि जब हम पंक्ति #i को स्कैन करते हैं तो हम पंक्ति # i-1 के लिए पंक्ति स्थिति को पहले से ही जानते हैं। इसलिए, जब हम पंक्ति को स्कैन कर रहे हैं #i तो हम पंक्ति # i-1 को साफ़ कर सकते हैं यदि यह आवश्यक है।

स्तंभों के लिए एक ही समाधान काम करता है, लेकिन हमें पंक्तियों और स्तंभों को एक साथ स्कैन करने की आवश्यकता होती है, जबकि डेटा अगले पुनरावृत्ति द्वारा नहीं बदला जाता है।

पहली पंक्ति और पहले कॉलम की स्थिति को संग्रहीत करने के लिए दो बूलियनों की आवश्यकता होती है, क्योंकि एल्गोरिथ्म के मुख्य भाग के निष्पादन के दौरान उनके मूल्यों को बदल दिया जाएगा।

अधिक बूलियनों को जोड़ने से बचने के लिए हम मैट्रिक्स की पहली पंक्ति और स्तंभ में पंक्तियों और स्तंभों के लिए "स्पष्ट" ध्वज का भंडारण कर रहे हैं।

public void Run()
{
    const int N = 5;

    int[,] m = new int[N, N] 
                {{ 1, 0, 1, 1, 0 },
                { 1, 1, 1, 1, 0 },
                { 1, 1, 1, 1, 1 },
                { 1, 0, 1, 1, 1 },
                { 1, 1, 1, 1, 1 }};

    bool keepFirstRow = (m[0, 0] == 1);
    bool keepFirstColumn = keepFirstRow;

    for (int i = 1; i < N; i++)
    {
        keepFirstRow = keepFirstRow && (m[0, i] == 1);
        keepFirstColumn = keepFirstColumn && (m[i, 0] == 1);
    }

    Print(m); // show initial setup

    m[0, 0] = 1; // to protect first row from clearing by "second pass"

    // "second pass" is performed over i-1 row/column, 
    // so we use one more index just to complete "second pass" over the 
    // last row/column
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= N; j++)
        {
            // "first pass" - searcing for zeroes in row/column #i
            // when i = N || j == N it is additional pass for clearing 
            // the previous row/column
            // j >= i because cells with j < i may be already modified 
            // by "second pass" part
            if (i < N && j < N && j >= i) 
            {
                m[i, 0] &= m[i, j];
                m[0, j] &= m[i, j];

                m[0, i] &= m[j, i];
                m[j, 0] &= m[j, i];
            }

            // "second pass" - clearing the row/column scanned 
            // in the previous iteration
            if (m[i - 1, 0] == 0 && j < N)
            {
                m[i - 1, j] = 0;
            }

            if (m[0, i - 1] == 0 && j < N)
            {
                m[j, i - 1] = 0;
            }
        }

        Print(m);
    }

    // Clear first row/column if needed
    if (!keepFirstRow || !keepFirstColumn)
    {
        for (int i = 0; i < N; i++)
        {
            if (!keepFirstRow)
            {
                m[0, i] = 0;
            }
            if (!keepFirstColumn)
            {
                m[i, 0] = 0;
            }
        }
    }

    Print(m);

    Console.ReadLine();
}

private static void Print(int[,] m)
{
    for (int i = 0; i < m.GetLength(0); i++)
    {
        for (int j = 0; j < m.GetLength(1); j++)
        {
            Console.Write(" " + m[i, j]);
        }
        Console.WriteLine();
    }
    Console.WriteLine();
}

0

ऐसा लगता है कि कोई अतिरिक्त स्थान आवश्यकताओं के साथ निम्नलिखित काम करता है:

पहला ध्यान दें कि पंक्ति के तत्वों को गुणा करना उस पंक्ति के तत्वों को जिसमें एक तत्व है, वांछित मूल्य देता है।

किसी भी अतिरिक्त स्थान का उपयोग नहीं करने के लिए (एक नई मैट्रिक्स नहीं बनाने और इसे भरने के बजाय सीधे मैट्रिक्स में परिवर्तन लागू करें), मैट्रिक्स के ऊपर बाईं ओर शुरू करें और किसी भी ixi मैट्रिक्स के लिए गणना करें (कि "शुरू होता है" (0) , किसी भी सूचकांक के साथ किसी भी तत्व पर विचार करने से पहले)।

आशा है कि यह काम करता है (हेवेंट टेस्टेट)


गलत लगता है। मान लें कि पंक्ति 0 में केवल 1 मान हैं। यदि आपके द्वारा निर्धारित अंतिम मान (0,0) 0 है, तो आप बाद में पूर्ण पंक्ति को 0 पर सेट कर देंगे, जो आवश्यक रूप से सही नहीं है। आपको वास्तव में अपने सिद्धांत का उपयोग करके, गतिशील प्रोग्रामिंग शैली करने के लिए प्रति सेल 2 मानों को संग्रहीत करने की आवश्यकता है।
ईल श्नाइडर

यकीन है, आप सही हैं। दो मानों को संग्रहीत करने के बजाय, मैं एक तीसरी सकारात्मकता का उपयोग कर सकता हूं, -1 का कहना है कि यह उन कोशिकाओं के लिए है जो 1 "पुराने" मैट्रिक्स में 1 हैं जो अंततः 0. द्वारा प्रतिस्थापित किया जाएगा, इस तरह, एक को पूर्ण रूप से लेना होगा गुणन के बाद मान। अंत में, सभी -1 को 0 के द्वारा बदल दिया जाता है।
DFF

0

यह है परीक्षण किया C ++ अलग N के लिए, और है:
एक पास , दो bools , सं प्रत्यावर्तन , कोई अतिरिक्त मेमोरी , ARBITRARLY बड़ी एन के लिए रखती है
(अब तक समाधान यहाँ से कोई भी नहीं ये सब।)

विशेष रूप से, मैं दो लूप काउंटरों को ठीक कर रहा हूं। मेरे पास दो कॉन्स्टेड अहस्ताक्षरित हैं, जो केवल पठनीयता के लिए हर बार गणना किए जाने के बजाय मौजूद हैं। बाहरी लूप का अंतराल [0, N] है, और आंतरिक लूप का अंतराल [1, n - 1] है। स्विच स्टेटमेंट लूप में है जो ज्यादातर स्पष्ट रूप से दिखाने के लिए मौजूद है कि यह वास्तव में सिर्फ एक पास है।

एल्गोरिथम रणनीति:

पहली ट्रिक हमें मैट्रिक्स की सामग्री को संचित करने के लिए मैट्रिक्स से स्वयं एक पंक्ति और एक कॉलम है, यह मेमोरी सभी को ऑफलोड करके उपलब्ध होती है जो हमें वास्तव में पहली पंक्ति और कॉलम से दो बूलियन में जानने की आवश्यकता होती है। दूसरी चाल यह है कि सब-मैट्रिक्स और उसके सूचकांकों के समरूपता का उपयोग करके एक से दो पास प्राप्त करें।

एल्गोरिथम सिनोप्सिस:

  • पहली पंक्ति को स्कैन करें और स्टोर करें यदि वे एक बूलियन में सभी हैं, तो पहले कॉलम के लिए एक दूसरे बूलियन में परिणाम का भंडारण करें।
  • पहली पंक्ति और पहले कॉलम को छोड़कर उप-मैट्रिक्स के लिए: के माध्यम से पुनरावृत्त, बाएं से दाएं, ऊपर से नीचे, क्योंकि कोई एक पैरा पढ़ेगा। प्रत्येक तत्व पर जाने पर, उप-मैट्रिक्स का उल्टा दौरा करने पर, संबंधित तत्व पर भी जाएँ। प्रत्येक तत्व का दौरा किया और उसके मूल्य में जहां इसकी पंक्ति पहले कॉलम को पार करती है, और इसके मूल्य में भी जहां इसका कॉलम पहली पंक्ति को पार करता है।
  • एक बार उप-मैट्रिक्स के केंद्र तक पहुंचने के बाद, ऊपर के रूप में एक साथ दो तत्वों का दौरा करना जारी रखें। हालाँकि अब विज़िट किए गए तत्वों के मान को AND पर सेट करें जहाँ इसकी पंक्ति पहले कॉलम को पार करती है, और जहाँ इसका कॉलम पहली पंक्ति को पार करता है। इसके बाद, उप-मैट्रिक्स पूरा हो गया है।
  • पहली पंक्ति सेट करने के लिए भीख मांगने के लिए गणना किए गए दो बूलियन चर का उपयोग करें, और उनके सही मानों के लिए पहला कॉलम।

अस्थायी C ++ कार्यान्वयन:

template<unsigned n>
void SidewaysAndRowColumn(int((&m)[n])[n]) {
    bool fcol = m[0][0] ? true : false;
    bool frow = m[0][0] ? true : false;
    for (unsigned d = 0; d <= n; ++d) {
        for (unsigned i = 1; i < n; ++i) {
            switch (d) {
                case 0:
                    frow    = frow && m[d][i];
                    fcol    = fcol && m[i][d];
                    break;
                default:
                {
                    unsigned const rd = n - d;
                    unsigned const ri = n - i;
                    if (d * n + i < rd * n + ri)
                    {
                        m[ d][ 0] &= m[ d][ i];
                        m[ 0][ d] &= m[ i][ d];
                        m[ 0][ i] &= m[ d][ i];
                        m[ i][ 0] &= m[ i][ d];
                        m[rd][ 0] &= m[rd][ri];
                        m[ 0][rd] &= m[ri][rd];
                        m[ 0][ri] &= m[rd][ri];
                        m[ri][ 0] &= m[ri][rd];
                    }
                    else
                    {
                        m[ d][ i] = m[ d][0] & m[0][ i];
                        m[rd][ri] = m[rd][0] & m[0][ri];
                    }
                    break;
                }
                case n:
                    if (!frow)
                        m[0][i] = 0;
                    if (!fcol)
                        m[i][0] = 0;
            };
        }
    }
    m[0][0] = (frow && fcol) ? 1 : 0;
}

0

ठीक है, मुझे पता है कि यह काफी मेल नहीं खाता है, लेकिन मैंने इसे एक पास में दो बूल के बजाय एक बूल और बाइट का उपयोग करके प्राप्त किया ... करीब। मैं इसकी दक्षता के लिए भी प्रतिज्ञा नहीं करूंगा लेकिन इस प्रकार के प्रश्नों के लिए प्रायः इष्टतम समाधानों की आवश्यकता होती है।

private static void doIt(byte[,] matrix)
{
    byte zeroCols = 0;
    bool zeroRow = false;

    for (int row = 0; row <= matrix.GetUpperBound(0); row++)
    {
        zeroRow = false;
        for (int col = 0; col <= matrix.GetUpperBound(1); col++)
        {
            if (matrix[row, col] == 0)
            {

                zeroRow = true;
                zeroCols |= (byte)(Math.Pow(2, col));

                // reset this column in previous rows
                for (int innerRow = 0; innerRow < row; innerRow++)
                {
                    matrix[innerRow, col] = 0;
                }

                // reset the previous columns in this row
                for (int innerCol = 0; innerCol < col; innerCol++)
                {
                    matrix[row, innerCol] = 0;
                }
            }
            else if ((int)(zeroCols & ((byte)Math.Pow(2, col))) > 0)
            {
                matrix[row, col] = 0;
            }

            // Force the row to zero
            if (zeroRow) { matrix[row, col] = 0; }
        }
    }
}

0

आप इसे एक पास में कर सकते हैं।

[संपादित करें: सरल, लेकिन गलत समाधान हटाया गया]

आपको किसी भी एकल-पास विधि की तुलना में दो पास करके बेहतर प्रदर्शन प्राप्त करना चाहिए: एक पंक्ति / कॉलम की जानकारी जमा करने के लिए, और एक इसे लागू करने के लिए। सरणी (पंक्ति-प्रमुख क्रम में) सुसंगत रूप से एक्सेस की जाती है; कैश आकार से अधिक सरणियों के लिए (लेकिन जिनकी पंक्तियों को कैश में फिट किया जा सकता है), डेटा को दो बार मेमोरी से पढ़ा जाना चाहिए, और एक बार संग्रहीत किया जाना चाहिए:

void fixmatrix2(int M[][], int rows, int cols) {
    bool clearZeroRow= false;
    bool clearZeroCol= false;
    for(int j=0; j < cols; ++j) {
        if( ! M[0][j] ) {
            clearZeroRow= true;
        }
    }
    for(int i=1; i < rows; ++i) { // scan/accumulate pass
        if( ! M[i][0] ) {
            clearZeroCol= true;
        }
        for(int j=1; j < cols; ++j) {
            if( ! M[i][j] ) {
                M[0][j]= 0;
                M[i][0]= 0;
            }
        }
    }
    for(int i=1; i < rows; ++i) { // update pass
        if( M[i][0] ) {
            for(int j=0; j < cols; ++j) {
                if( ! M[j][0] ) {
                    M[i][j]= 0;
                }
            }
        } else {
            for(int j=0; j < cols; ++j) {
                M[i][j]= 0;
            }
        }
        if(clearZeroCol) {
            M[i][0]= 0;
        }
    }
    if(clearZeroRow) {
        for(int j=0; j < cols; ++j) {
            M[0][j]= 0;
        }
    }
}

0

सबसे आसान उपाय जो मैं सोच सकता हूं, वह नीचे दिया गया है। तर्क यह दर्ज करना है कि कौन सी पंक्ति और कॉलम को पुनरावृति करते समय शून्य सेट करना है।

import java.util.HashSet;
import java.util.Set;

public class MatrixExamples {
    public static void zeroOut(int[][] myArray) {
        Set<Integer> rowsToZero = new HashSet<>();
        Set<Integer> columnsToZero = new HashSet<>();

        for (int i = 0; i < myArray.length; i++) { 
            for (int j = 0; j < myArray.length; j++) {
                if (myArray[i][j] == 0) {
                    rowsToZero.add(i);
                    columnsToZero.add(j);
                }
            }
        }

        for (int i : rowsToZero) {
            for (int j = 0; j < myArray.length; j++) {
                myArray[i][j] = 0;
            }
        }

        for (int i : columnsToZero) {
            for (int j = 0; j < myArray.length; j++) {
                myArray[j][i] = 0;
            }
        }

        for (int i = 0; i < myArray.length; i++) { // record which rows and                                             // columns will be zeroed
            for (int j = 0; j < myArray.length; j++) {
                System.out.print(myArray[i][j] + ",");
            if(j == myArray.length-1)
                System.out.println();
            }
        }

    }

    public static void main(String[] args) {
        int[][] a = { { 1, 0, 1, 1, 0 }, { 0, 1, 1, 1, 0 }, { 1, 1, 1, 1, 1 },
                { 1, 0, 1, 1, 1 }, { 1, 1, 1, 1, 1 } };
        zeroOut(a);
    }
}

0

यहाँ परीक्षण के साथ मेरा रूबी कार्यान्वयन शामिल है, यह O (MN) स्थान लेगा। यदि हम एक वास्तविक समय अद्यतन चाहते हैं (जैसे हम शून्य का पता लगाने के पहले लूप का इंतजार करने के बजाय शून्य को खोजने पर परिणाम दिखाते हैं) तो हम बस एक और वर्ग चर बना सकते हैं जैसे @outputऔर जब भी हम एक शून्य पाते हैं हम अपडेट करते हैं @outputऔर नहीं @input

require "spec_helper"


class Matrix
    def initialize(input)
        @input  = input
        @zeros  = []
    end

    def solve
        @input.each_with_index do |row, i|          
            row.each_with_index do |element, j|                             
                @zeros << [i,j] if element == 0
            end
        end

        @zeros.each do |x,y|
            set_h_zero(x)
            set_v_zero(y)
        end

        @input
    end


    private 

    def set_h_zero(row)     
        @input[row].map!{0}     
    end

    def set_v_zero(col)
        @input.size.times do |r|
            @input[r][col] = 0
        end
    end
end


describe "Matrix" do
  it "Should set the row and column of Zero to Zeros" do
    input =  [[1, 3, 4, 9, 0], 
              [0, 3, 5, 0, 8], 
              [1, 9, 6, 1, 9], 
              [8, 3, 2, 0, 3]]

    expected = [[0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0],
                [0, 9, 6, 0, 0],
                [0, 0, 0, 0, 0]]

    matrix = Matrix.new(input)

    expect(matrix.solve).to eq(expected)
  end
end

0

नीचे दिया गया कोड आकार m, n का एक मैट्रिक्स बनाता है। पहले मैट्रिक्स के आयाम तय करें। मैं मैट्रिक्स [m] [n] को अनियमित रूप से 0..10 के बीच की संख्या के साथ भरना चाहता था। फिर समान आयामों का एक और मैट्रिक्स बनाएं और इसे -1s (अंतिम मैट्रिक्स) के साथ भरें। फिर प्रारंभिक मैट्रिक्स के माध्यम से यह देखने के लिए कि क्या आप हिट करेंगे 0. जब आप स्थान (x, y) पर हिट करते हैं, तो अंतिम मैट्रिक्स पर जाएं और पंक्ति x को 0s और कॉलम y को 0 s के साथ भरें। अंतिम मैट्रिक्स के माध्यम से अंत में पढ़ा जाता है, यदि मान -1 (मूल मूल्य) है, तो मूल्य को प्रारंभिक मैट्रिक्स के अंतिम स्थान पर कॉपी करें।

public static void main(String[] args) {
    int m = 5;
    int n = 4;
    int[][] matrixInitial = initMatrix(m, n); // 5x4 matrix init randomly
    int[][] matrixFinal = matrixNull(matrixInitial, m, n); 
    for (int i = 0; i < m; i++) {
        System.out.println(Arrays.toString(matrixFinal[i]));
    }
}

public static int[][] matrixNull(int[][] matrixInitial, int m, int n) {
    int[][] matrixFinal = initFinal(m, n); // create a matrix with mxn and init it with all -1
    for (int i = 0; i < m; i++) { // iterate in initial matrix
        for (int j = 0; j < n; j++) {
            if(matrixInitial[i][j] == 0){ // if a value is 0 make rows and columns 0
                makeZeroX(matrixFinal, i, j, m, n); 
            }
        }
    }

    for (int i = 0; i < m; i++) { // if value is -1 (original) copy from initial
        for (int j = 0; j < n; j++) {
            if(matrixFinal[i][j] == -1) {
                matrixFinal[i][j] = matrixInitial[i][j];
            }
        }
    }
    return matrixFinal;
}

private static void makeZeroX(int[][] matrixFinal, int x, int y, int m, int n) {
        for (int j = 0; j < n; j++) { // make all row 0
            matrixFinal[x][j] = 0;
        }
        for(int i = 0; i < m; i++) { // make all column 0
            matrixFinal[i][y] = 0; 
        }
}

private static int[][] initMatrix(int m, int n) {

    int[][] matrix = new int[m][n];
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            Random rn = new Random();
            int random = rn.nextInt(10);
            matrix[i][j] = random;
        }
    }

    for (int i = 0; i < m; i++) {
        System.out.println(Arrays.toString(matrix[i]));
    }
    System.out.println("******");
    return matrix;
}

private static int[][] initFinal(int m, int n) {

    int[][] matrix = new int[m][n];
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            matrix[i][j] = -1;
        }
    }
    return matrix;
}

// another approach
/**
 * @param matrixInitial
 * @param m
 * @param n
 * @return
 */
private static int[][] matrixNullNew(int[][] matrixInitial, int m, int n) {
    List<Integer> zeroRowList = new ArrayList<>(); // Store rows with 0
    List<Integer> zeroColumnList = new ArrayList<>(); // Store columns with 0
    for (int i = 0; i < m; i++) { // read through the matrix when you hit 0 add the column to zeroColumnList and add
                                  // the row to zeroRowList
        for (int j = 0; j < n; j++) {
            if (matrixInitial[i][j] == 0) {
                if (!zeroRowList.contains(i)) {
                    zeroRowList.add(i);
                }
                if (!zeroColumnList.contains(j)) {
                    zeroColumnList.add(j);
                }
            }
        }
    }

    for (int a = 0; a < m; a++) {
        if (zeroRowList.contains(a)) { // if the row has 0
            for (int b = 0; b < n; b++) {
                matrixInitial[a][b] = 0; // replace all row with zero
            }
        }
    }

    for (int b = 0; b < n; b++) {
        if (zeroColumnList.contains(b)) { // if the column has 0
            for (int a = 0; a < m; a++) {
                matrixInitial[a][b] = 0; // replace all column with zero
            }
        }
    }
    return matrixInitial;
}

आप अपने द्वारा पोस्ट किए गए कोड को कोई स्पष्टीकरण या संदर्भ नहीं देते हैं।
एरोन

आशा है कि अब बेहतर होगा। चेतावनी के लिए धन्यवाद। मैं अधिक स्पष्ट करना चाहूंगा, अगर यह आपके लिए स्पष्ट नहीं है।
user3743369

0

यहाँ मेरा समाधान है। जैसा कि आप M * N मैट्रिक्स को देखते हुए कोड से देख सकते हैं, यह पूरी पंक्ति को शून्य पर सेट कर देता है क्योंकि यह उस पंक्ति में एक शून्य का निरीक्षण करता है। मेरे समाधान की समय जटिलता O (M * N) है। मैं पूरी कक्षा को साझा कर रहा हूं जिसमें परीक्षण के लिए एक स्थिर आबादी सरणी और कंसोल में परिणाम देखने के लिए एक प्रदर्शन सरणी विधि है।

public class EntireRowSetToZero {
    static int arr[][] = new int[3][4];
    static {

    arr[0][0] = 1;
    arr[0][1] = 9;
    arr[0][2] = 2;
    arr[0][3] = 2;

    arr[1][0] = 1;
    arr[1][1] = 5;
    arr[1][2] = 88;
    arr[1][3] = 7;

    arr[2][0] = 0;
    arr[2][1] = 8;
    arr[2][2] = 4;
    arr[2][3] = 4;
}

public static void main(String[] args) {
    displayArr(EntireRowSetToZero.arr, 3, 4);
    setRowToZero(EntireRowSetToZero.arr);
    System.out.println("--------------");
    displayArr(EntireRowSetToZero.arr, 3, 4);


}

static int[][] setRowToZero(int[][] arr) {
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[i].length; j++) {
            if(arr[i][j]==0){
                arr[i]=new int[arr[i].length];
            }
        }

    }
    return arr;
}

static void displayArr(int[][] arr, int n, int k) {

    for (int i = 0; i < n; i++) {

        for (int j = 0; j < k; j++) {
            System.out.print(arr[i][j] + " ");
        }
        System.out.println("");
    }

}

}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.