বাইনারি সংখ্যা অনুসারে শব্দগুলির তালিকা তৈরি করুন


12

আমার একটি ম্যাট্রিক্স রয়েছে যা দেখতে নীচের মত দেখাচ্ছে:

ইনপুট :

A   B   C   D   E   F   G   H   I 
0   0   0   0   1   0   0   0   1
0   0   0   1   0   0   0   0   0  
0   0   0   1   0   0   0   0   0  
1   0   0   0   0   0   0   0   0  
1   0   1   0   0   0   1   0   0  
1   0   0   1   0   0   0   1   0  
1   0   0   0   1   1   1   0   0  

এবং আমি প্রতিটি সারির জন্য মান 1 এর সাথে সম্পর্কিত চিঠির তালিকাটি বের করতে চাই।

আউটপুট :

E,I 
D
D
A
A,C,G  
A,D,H  
A,E,F,G  

আমি শিরোনামকে বিভক্ত করার এবং শব্দগুলির সাথে সংখ্যার সাথে মিল রাখার চেষ্টা করেছি কিন্তু আমি ব্যর্থ হয়েছি।

উত্তর:


12

ইন awk:

NR == 1 { for(column=1; column <= NF; column++) values[column]=$column; }
NR > 1 { output=""
        for(column=1; column <= NF; column++)
                if($column) output=output ? output "," values[column] : values[column]
        print output }

6
এছাড়াও ব্যবহার করতে পারেনNR == 1 { split($0,values) }
— সন্দীপ

এটি দ্বিতীয় লাইন এড়িয়ে চলেছে। nextপ্রথম লাইনের শেষে একটি রাখার বিষয়টি বিবেচনা করুন যাতে আপনার পরবর্তী লাইনের জন্য বিপরীত অবস্থার পরীক্ষা করতে হবে না।
— এড মর্টন

1
আসল ইনপুট পাঠ্যের এটিতে একটি অতিরিক্ত ফাঁকা রেখা উপস্থিত ছিল যা আমি কোড করে রেখেছিলাম। এটি এডিট করা হয়েছে, সুতরাং কেবল পরিবর্তন NR > 2করুন NR > 1।
— জেফ শ্যাচলার

1
"গল্ফিং" টিপের জন্য আপনাকে ধন্যবাদ, সন্দীপ! আমি মনে করি যে আমি স্পষ্টতাকে 'লুপের জন্য পছন্দ করি কারণ এটি দেহের' ফর 'লুপের সাথে দৃষ্টিভঙ্গি / যৌক্তিকভাবে লাইন করে যায়।
— জেফ শ্যাচলার

1
@ ফিউশন.স্লোপ, হয় সম্পূর্ণ কোডটি একটি একক-উদ্ধৃত যুক্তি দিয়ে পাস করুন awk, অথবা কোডটি একটি ফাইলের মধ্যে পেস্ট করুন এবং এটি দিয়ে চালানawk -f that.script.file input-file
— জেফ শ্যাচলার

6

সঙ্গে অন্য এক perl

$ perl -lane 'if($. == 1){ @h=@F }
              else{@i = grep {$F[$_]==1} (0..$#F); print join ",",@h[@i]}
             ' ip.txt
E,I
D
D
A
A,C,G
A,D,H
A,E,F,G
  • -a@Fঅ্যারেতে উপলভ্য, সাদা-স্পেসে ইনপুট লাইন বিভক্ত করার বিকল্প
  • if($. == 1){ @h=@F } প্রথম লাইনে শিরোনাম সংরক্ষণ করুন
  • @i = grep {$F[$_]==1} (0..$#F) প্রবেশের তালিকা থাকলে সংরক্ষণ করুন 1
  • print join ",",@h[@i],বিভাজক হিসাবে ব্যবহার করে কেবল শিরোনাম অ্যারে থেকে সূচকগুলি মুদ্রণ করুন

4

এখনও এটি মজাদার জন্য, একটি zshসংস্করণ:

{
   read -A a  &&
   while read -A b; do
     echo ${(j<,>)${(s<>)${(j<>)a:^b}//(?0|1)}}
   done
} < file
  • ${a:^b} দুটি অ্যারে জিপ করুন, যাতে আপনি একটি 0 বি 0 সি 0 ডি 0 ই 0 এফ 0 জি 0 এইচ 0 আই 1 পান
  • ${(j<>)...} এর মধ্যে কিছুই না দিয়ে উপাদানগুলিতে যোগ দেয় তাই এটি A0B0C0D0E1F0G0H0I1 হয়ে যায়
  • ${...//(?0|1)}আমরা এটিটি ছাঁটাই ?0এবং 1এটি থেকে এটি EI হয়ে যায়:
  • ${(s<>)...} চিঠি অনুসারে একটি উপাদানের অ্যারে পেতে কিছুইতে বিভক্ত করুন: EI
  • ${(j<,>)...},-> ই, আই সহ যাদের সাথে যোগ দিন ।

এই ঠিক একটি সহজ বাশ অধিকার?
— fusion.slope

1
@ ফিউশন.স্লোপ, না, এটির zshথেকে আলাদা শেল bash(এবং আরও শক্তিশালী এবং আপনি যদি আমাকে জিজ্ঞাসা করেন তবে আরও ভাল নকশা সহ) এখানে বর্ণিত বৈশিষ্ট্যগুলি নয় , bashকেবলমাত্র zshএর বৈশিষ্ট্যটির (যেমন , ) একটি ক্ষুদ্র ক্ষুদ্র অংশ ধার নিয়েছে , বেশিরভাগ বৈশিষ্ট্যই অন্যথায় ধার করা হয়েছে । {1..4}<<<**/*bashksh
— স্টাফেন চ্যাজেলাস

3

আর একটি বিশ্রী সমাধান:

awk 'NR==1{ split($0,a); next }   # capture and print `header` fields
     { for (i=1;i<=NF;i++)         # iterating through value fields `[0 1 ...]`
           if ($i) { printf "%s",(f?","a[i]:a[i]); f=1 } 
       f=0; print "" 
     }' file

আউটপুট:

E,I
D
D
A
A,C,G
A,D,H
A,E,F,G

2

এখানে পার্লের একটি সমাধান দেওয়া হয়েছে:

use strict;

my @header = split /\s+/, <>;
<>; ## Skip blank line
while (<>) {
    my @flags = split /\s+/;
    my @letters = ();
    for my $i (0 .. scalar @flags - 1) {
        push @letters, $header[$i] if $flags[$i];
    }

    print join(',', @letters), "\n";
}

এটি শিরোনামে শিরোনাম কলামগুলি পাঠ করে এবং তারপরে, প্রতিটি ডেটা সারির জন্য, মিলিয়ে ডেটা কলামটি সত্য হিসাবে মূল্যায়ন করলে কলামের নাম আউটপুট অ্যারে অনুলিপি করে। কলামের নামগুলি পরে কমা-বিচ্ছিন্ন মুদ্রিত হয়।


2

sedএটি মজাদার জন্য একটি :

sed '
  s/ //g
  1{h;d;}
  G;s/^/\
/
  :1
    s/\n0\(.*\n\)./\
\1/
    s/\n1\(.*\n\)\(.\)/\2\
\1/
  t1
  s/\n.*//
  s/./&,/g;s/,$//'

জিএনইউ দিয়ে sedআপনি এটিকে কিছুটা স্পষ্ট করে তুলতে পারেন:

sed -E '
  s/ //g # strip the spaces

  1{h;d} # hold the first line

  G;s/^/\n/ # append the held line and prepend an empty line so the
            # pattern space becomes <NL>010101010<NL>ABCDEFGHI we will
            # build the translated version in the part before the first NL
            # eating one character at a time off the start of the
            # 010101010 and ABCDEFGHI parts in a loop:
  :1
    s/\n0(.*\n)./\n\1/     # ...<NL>0...<NL>CDEFGHI becomes
                           # ...<NL>...<NL>DEFGHI (0 gone along with C)

    s/\n1(.*\n)(.)/\2\n\1/ # ...<NL>1...<NL>CDEFGHI becomes
                           # ...C<NL>...<NL>DEFGHI (1 gone but C moved to 
                           #                        the translated part)
  t1 # loop as long as any of those s commands succeed

  s/\n.*// # in the end we have "ADG<NL><NL>", strip those NLs

  s/./,&/2g # insert a , before the 2nd and following characters'

একটি সামান্য সংক্ষিপ্ত সংস্করণ, ধরে নেওয়া এই যে প্রতিটি লাইনে সর্বদা একই সংখ্যার সংখ্যা থাকে:

sed -E '
  s/ //g
  1{H;d}
  G
  :1
    s/^0(.*\n)./\1/
    s/^1(.*\n)(.*\n)(.)/\1\3\2/
  t1
  s/\n//g
  s/./,&/2g'

উপরের মত একই আমরা অনুবাদ করা এবং সূচক অংশগুলি অদলবদল করছি যা কিছু অপ্টিমাইজেশনের জন্য অনুমতি দেয় except


আপনি যদি ব্যাখ্যা করতে পারেন তবে সম্প্রদায়ের পক্ষে ভাল হবে। অগ্রিম ধন্যবাদ
— fusion.slope

1
@ ফিউশন.স্লোপ, সম্পাদনা দেখুন।
— স্টাফেন চেজেলাস

টি 1 কমান্ড সহ লুপটি চমৎকার!
— fusion.slope

1

python3

python3 -c '
import sys
header = next(sys.stdin).rstrip().split()
for line in sys.stdin:
  print(*(h*int(f) for (h, f) in zip(header, line.rstrip().split()) if int(f)), sep=",")

  ' <file
E,I
D
D
A
A,C,G
A,D,H
A,E,F,G

0

খাঁটি বাশ সমাধান:

read -a h
while read -a r
do (
    for i in ${!r[@]}
    do 
        (( r[i] == 1 )) && y[i]=${h[i]}
    done
    IFS=,
    echo "${y[*]}")
done

3
এটি কীভাবে সমস্যার সমাধান করে তা ব্যাখ্যা করুন।
— স্কট

পাঠকের জন্য অনুশীলন হিসাবে এটি বাকি রয়েছে। বেসিক বাশ জ্ঞান ধরে নেওয়া LESS="+/^ {3}Array" man bashবাশ অ্যারেগুলির জন্য প্রয়োজনীয় সমস্ত তথ্য দেওয়া উচিত। যে কোনও সহায়ক স্পষ্টতা যোগ করতে আপনি উত্তর সম্পাদনা করতে নির্দ্বিধায়।
— ডেভিড ওঙ্গারো

-1
 void Main(string[] args)
        {
            int[,] numbers = new int[,]
            {
            {0, 0, 0, 0, 1, 0, 0, 0, 1},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {1, 0, 0, 0, 0, 0, 0, 0, 0},
            {1, 0, 1, 0, 0, 0, 1, 0, 0},
            {1, 0, 0, 1, 0, 0, 0, 1, 0},
            {1, 0, 0, 0, 1, 1, 1, 0, 0}
            };
            string letters = "ABCDEFGHI";
            for (int row = 0; row < 7; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    if (numbers[row, col] == 1)
                        Console.Write(letters[col]);
                }
                Console.WriteLine();
            }
        }

3
এটি কী করে এবং এটি কীভাবে কাজ করে তা দয়া করে ব্যাখ্যা করুন।
— স্কট

দয়া করে ভাষাও।
— fusion.slope
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.