Moim zadaniem domowym jest ciąg i podzielenie go na kawałki przy każdej nowej linii. Nie mam pojęcia co robić! Proszę pomóż!
Uwaga: jest to pytanie trollujące kod . Proszę nie brać poważnie pytania i / lub odpowiedzi. Więcej informacji tutaj .
code-trolling
Turion
źródło
źródło
Odpowiedzi:
do
Podstępny problem dla początkujących klas programowania C! Najpierw musisz zrozumieć kilka podstaw na ten skomplikowany temat.
Ciąg jest sekwencją złożoną tylko z znaków . Oznacza to, że aby programiści mogli wskazać „niewidzialną” rzecz (nie jest to spacja, która liczy się jako znak), musisz w jakiś sposób użyć specjalnej sekwencji znaków, aby oznaczać tę niewidzialną rzecz.
W systemie Windows nowa linia to ciąg dwóch znaków w ciągu: odwrotny ukośnik i n (lub ciąg
"\n"
)W komputerach Mac z systemem Linux lub OS / X jest to ciąg czterech znaków: ukośnik odwrotny, n, ukośnik odwrotny, a następnie r: (lub
"\n\r"
).(Ciekawa uwaga historyczna: na starszych Macintoshach była to inna sekwencja czterech znaków: „\ r \ n” ... całkowicie wstecz od tego, jak Unix robił rzeczy! Historia kręci dziwnymi drogami.)
Może się wydawać, że Linux jest bardziej marnotrawny niż Windows, ale w rzeczywistości lepszym pomysłem jest użycie dłuższej sekwencji. Ponieważ system Windows używa tak krótkiej sekwencji, środowisko wykonawcze w języku C nie może wydrukować rzeczywistych liter
\n
bez specjalnych wywołań systemowych. Zwykle możesz to zrobić w systemie Linux bez wywołania systemowego (może nawet drukować\n\
lub\n\q
... cokolwiek innego\n\r
). Ale ponieważ C ma być platformą, wymusza najniższy wspólny mianownik. Więc zawsze będziesz widzieć\n
w swojej książce.(Uwaga: jeśli zastanawiasz się, o czym mówimy
\n
bez uzyskiwania nowych wierszy za każdym razem, StackOverflow jest napisany prawie całkowicie w HTML ... nie C. Jest więc o wiele bardziej nowoczesny. Wiele z tych starych aspektów C to adresowane przez rzeczy, o których mogłeś słyszeć, takie jak CLANG i LLVM.)Ale wracając do tego, nad czym pracujemy. Wyobraźmy sobie ciąg z trzema kawałkami i dwoma znakami nowej linii, takimi jak:
Możesz zobaczyć, że długość tego ciągu wynosi 3 + 2 + 3 + 2 + 3 = 13. Musisz więc utworzyć bufor o długości 13, a programiści C zawsze dodają jeden do rozmiaru swoich tablic, aby być bezpiecznym. Utwórz bufor i skopiuj do niego ciąg:
Teraz musisz poszukać dwuznakowego wzorca reprezentującego nowy wiersz. Nie możesz szukać tylko odwrotnego ukośnika. Ponieważ C jest dość często używane do dzielenia łańcuchów, przy próbie zostanie wyświetlony błąd. Możesz to zobaczyć, jeśli spróbujesz napisać:
(Uwaga: w kompilatorze jest ustawienie, jeśli piszesz program, który szuka po prostu odwrotnych ukośników. Ale to niezwykle rzadkie; odwrotne ukośniki są bardzo rzadko używane, dlatego zostały wybrane do tego celu. Nie zmienimy tego włączać.)
Stwórzmy więc wzór, który naprawdę chcemy:
Kiedy chcemy porównać dwa ciągi o określonej długości, używamy
strncmp
. Porównuje pewną liczbę znaków potencjalnie większego ciągu i informuje, czy pasują do siebie, czy nie.strncmp("\nA", "\nB", 2)
Zwraca więc 1 (prawda). Dzieje się tak, mimo że ciągi nie są całkowicie równe na długości trzech ... ale ponieważ potrzebne są tylko dwa znaki.Przejdźmy więc przez nasz bufor, po jednym znaku na raz, szukając dwóch znaków pasujących do naszego wzorca. Za każdym razem, gdy znajdziemy dwuznakową sekwencję odwrotnego ukośnika, po której następuje n, użyjemy bardzo specjalnego wywołania systemowego (lub „syscall”),
putc
aby wydać specjalny rodzaj znaku: kod ASCII 10 , aby uzyskać fizyczną nową linię .Wynikiem tego programu jest pożądany wynik ... podział łańcucha!
\t
jest dla \ trollingu ......
...
...
źródło
Gratulacje! Twój ciąg powinien być teraz podzielony. Jeśli nie, powtarzaj kroki, aż będzie. Jeśli kilka razy powtórzyłeś kroki, a sznurek nie rozdzieli się, spróbuj użyć ostrzejszego nożyczki.
WYŁĄCZENIE ODPOWIEDZIALNOŚCI: Nie jestem odpowiedzialny za jakiekolwiek szkody wyrządzone tobie podczas procesu.
źródło
Pyton
Czuję się tak źle, że dostałeś tak oczywiste podchwytliwe pytanie jak zadanie domowe. Wysoce zaawansowany język, taki jak Python, czyni go prostym dwuliniowym:
Proszę głosować i zaakceptować.
źródło
do
W C jest to naprawdę łatwe:
Nazwij to tak:
Przykład roboczy:
http://codepad.org/GBHdz2MR
Dlaczego to zło:
printf
funkcji dzielenia ciągów#define
(a nawet tych, którzy rozumieją )źródło
Można to zrobić w kilku wierszach kodu za pomocą następującego prostego algorytmu:
Jest to jednak marnotrawstwo. Jest to zasadniczo liniowy algorytm wyszukiwania , który ma liniową złożoność czasową (O (n)). Pozwolę ci na bardziej zaawansowaną technikę: wyszukiwanie binarne . Wyszukiwanie binarne jest o wiele bardziej wydajne niż wyszukiwanie liniowe: ma tylko logarytmiczną złożoność czasu (O (log (n)). Oznacza to, że jeśli przestrzeń wyszukiwania jest dwa razy większa, czas wyszukiwania nie podwaja się, zwiększa się tylko o stała kwota!
Kod do wyszukiwania binarnego jest nieco bardziej skomplikowany, ponieważ wykorzystuje zaawansowane techniki rekurencji i dzielenia i zdobywania . Ale zdecydowanie warto, aby zwiększyć wydajność. Jeśli to prześlesz, spodziewam się, że dostaniesz dodatkowy kredyt.
Istota algorytmu jest następująca:
Nie określiłeś języka, więc napisałem go w języku Python. Oczywiście w prawdziwym świecie ludzie nie piszą w języku Python - używaj C lub C ++ (lub nawet lepiej, asemblera) do prawdziwej wydajności. Nie martw się, jeśli nie rozumiesz, co robi cały kod - jest to zdecydowanie coś zaawansowanego.
Oczywiście wszystkie stwierdzenia dotyczące wydajności są fałszywe. „Prosty” algorytm może być liniowy lub kwadratowy w zależności od jego interpretacji. Algorytm „zaawansowany” to Θ (n × log (n)) (w praktyce dość zbliżony do liniowego), ale chłopiec jest stałą multiplikatywną ze względu na nieustanne przebudowywanie listy (której implementacja w pewien sposób nie pozwala na przyspieszenie ).
Styl Python, styl komentarzy, stwierdzenia dotyczące wyboru języka i prawie wszystko inne w tym poście nie odzwierciedlają mojej faktycznej opinii ani nawyków.
źródło
Visual Basic
IO
Monada posiada funkcję, aby to zrobić!źródło
C ++
std::strstream
strstream
std::
prefiksuźródło
Python 3 (Neat and Clean)
źródło
#define
? ;-)Rubin
Cóż, najpierw widzisz, że musisz zrobić z tego tablicę
Teraz musisz umieścić elementy jako ciągi
Och, także usuń ten ostatni przecinek
Ups, zapomniałem, musisz wstawić nawiasy, aby były tablicą
Teraz wystarczy użyć łańcucha i gotowe
Zło
split
eval
'
lub,
źródło
Lua
Przykładowe dane wejściowe: Dane
"Hello\nworld\nstuff"
wyjściowe:
{"pieces","pieces","pieces","pieces","pieces","pieces"}
No i zapomniałem wspomnieć, że kod to O (n ^ 2)
źródło
Node.JS
To takie proste, każdy programista mógłby to zrobić.
Najpierw musimy zmienić
hosts
plik, aby.com, .net, .org
mapować na127.0.0.1
.a reszta to podstawowy Javascript, który każdy noob mógłby zrozumieć.
Proszę bardzo :)
źródło
string.split('/n');
o zdezorientowaniu ucznia teoretycznego :).Rubin
Ciągi w programowaniu są wykonane z Einsteintanium. Jako takie są niezwykle trudne do podzielenia.
Na szczęście mam doktorat z chemii i programowania, więc mogę pomóc.
Użyjemy do tego rubinu.
To jest złe, ponieważ:
źródło
SplitStr
zawsze dzieli znakami nowej linii, bez względu argument jest, nie wiem, czy zamierzonaC ++
Dzięki nowym, zaawansowanym funkcjom języka programowania C ++ można to łatwo rozwiązać za pomocą standardowej biblioteki, pamiętaj, aby nie wymyślać od nowa koła .
Edycja: Ta odpowiedź oczywiście stara się stworzyć coś głupio złożonego do trywialnego zadania, a jednocześnie nadużywając tak wielu narzędzi, jak tylko mogłem, wciąż będąc w stanie napisać kod.
Oto kilka rzeczy, na które należy zwrócić uwagę:
źródło
DO#
Wykorzystuje technologię rekurencji do przekształcania nowych linii w przecinki. Powstały ciąg CSV można łatwo podzielić na tablicę.
źródło
C ++
Wygląda całkowicie wiarygodnie i podręcznikowo aż do ostatniego wyrażenia. To nawet poprawne, po prostu spróbuj wyjaśnić to swojemu nauczycielowi.
Oczywiście nie ma uzasadnienia
std::for_each
, ale pozwala nam to na niewłaściwe użycie lambda. Ta lambda wygląda na to, że coś zwraca, ale w rzeczywistości tak nie jest. Operator trójskładnikowy służy tylko efektom ubocznym.źródło
W porządku! Tak więc problem ten jest bardzo łatwy dzięki użyciu kilku mało znanych funkcji Pythona, w tym instrukcji #define (ostatnio przeniesiono je z C ++) i automatycznej rejestracji metod we wbudowanych klasach.
Jakie to miłe?
Wyjaśnienie
... jest tu całkiem spora lista trollingu.
W rzeczywistości program działa (przynajmniej w Pythonie 3.3.0, oprócz problemu z wprowadzaniem tekstu w jednym wierszu), ponieważ wiele rzeczy, które sprawiają, że nie robi tego, co mówi, łączy się, aby faktycznie działał.
źródło
Cel LOLCODE
źródło
ANSI C
To standardowe zadanie, które wszyscy wykonaliśmy. To jest ogólnie przyjęte rozwiązanie.
Musisz dołączyć bibliotekę z odpowiednią funkcją do podziału i drukowania.
#include <stdio.h>
Utwórz ciąg, który chcesz podzielić:
const char * input = "First Line\nSecond Line\nThird Line\n";
Zwróć uwagę, jak użyłemconst
słowa kluczowego, aby zilustrować, że printf nie ma możliwości zmiany danych wejściowych. Jest to ważne, ponieważ zawsze chcesz zachować dane użytkownika w oryginalnej formie do celów prawnych.printf("%s", input);
wykonuje podział dla ciebie, jak widać w wynikach konsoli.getchar();
to tylko niewielka dodatkowa sztuczka, aby utrzymać konsolę w tyle podczas sprawdzania wyjścia.Dane wejściowe:
"First Line\nSecond Line\nThird Line\n"
Tworzy wynik:
źródło
Pyton
Możemy iteracyjnie użyć
find()
metody łańcuchowej Pythona do podzielenia łańcucha przy każdej nowej instancji linii (zauważ, że łańcuch wejściowy jest zakodowany na stałe jakoinput_str
, ale może zostać zastąpiony przez raw_input ()):Po uruchomieniu powyższego skryptu uzyskujemy oczekiwany wynik (zwróć uwagę, że początkowe i końcowe białe znaki są zgodne z podziałem łańcucha przy każdym wystąpieniu nowej linii):
źródło
PHP / GD
Dzielenie strun to bardzo skomplikowana sprawa. Chociaż kontynuowaliśmy i wprowadziliśmy dość podstawową implementację tego tak ważnego zadania domowego.
Działa bez żadnych zależności od najnowszej wersji PHP: Ilość przykładów ograniczona w opublikowanym kodzie, ponieważ mamy tutaj limit znaków około 40 000 znaków, który nie pasuje do przyzwoitej liczby łańcuchów demonstracyjnych.
Przykładowa wersja:
http://codepad.viper-7.com/YnGvCn
Dokładnie potwierdza twoje specyfikacje.
źródło
Nie chcę być wredny, więc oto działający kod Pythona, który dzieli twój łańcuch na części. Ponieważ jednak nie określiłeś, gdzie chcesz go podzielić, wybiorę tylko losowe lokalizacje. Mam nadzieję, że to w porządku.
źródło
Pyton
źródło
W przypadku języków, które obsługują wyrażenie regularne i mają
split
łatwo dostępne funkcje, należy zawsze używać go do dzielenia łańcucha. Pomaga to uniknąć ponownego wymyślania koła i zapewniać krótki i słodki kod. Użycie wyrażenia regularnego pozwala również przenieść kod na inny język bez zmiany wyrażenia regularnego.Złe rozwiązanie
Jest to oczywiste rozwiązanie, w którym podziale
\n
lub\r\n
:Jawa
PHP
To rozwiązanie jest śmieciem i nigdy nie powinno być używane. W dzisiejszych czasach nie ma sensu unikać Unicode, raczej każdy programista powinien go zaakceptować i upewnić się, że twoja aplikacja jest gotowa na Unicode. Jeśli rozważasz tylko
\n
lub\r\n
jako nowy separator linii, piszesz oprogramowanie w latach 90. W tej erze Unicode należy uznać U + 0085, U + 2028, U + 2029 jako prawidłowy separator linii. Ponieważ Unicode jest aktualizowany co jakiś czas i zwykle zajmuje trochę czasu, zanim zdasz sobie sprawę, że został zaktualizowany, do Unicode może zostać dodany nowy separator linii. Nie martw się, ponieważ wszystkie silniki wyrażeń regularnych są gotowe na Unicode i są regularnie aktualizowane, aby były zgodne z najnowszym standardem Unicode. Więc jeśli używasz tłumaczonego języka, Twój kod będzie aktualny bez robienia czegokolwiek.Zalecane rozwiązanie
Aby podzielić ciąg znaków przez terminator linii i być na bieżąco z ewolucją Unicode, podaj wyrażenie regularne
^
i określMULTILINE
tryb.Domyślnie
^
dopasowuje tylko początek łańcucha. WMULTILINE
trybie dopasowuje^
również początek linii, tj. Po zakończeniu linii.Na przykład:
Jawa
PHP
Zauważ, że z przodu znajduje się dodatkowy pusty ciąg znaków, wystarczy go usunąć lub zapętlić z indeksu 1.
Wyjaśnienie
Na pierwszy rzut oka wygląda to na dobrą odpowiedź z (nieco) działającym rozwiązaniem, w połączeniu z wyjaśnieniem z pewnymi zaleceniami kodowania najlepszych praktyk. Jednak samo rozwiązanie to troll ( „Wiem, użyję wyrażeń regularnych.” Teraz mają dwa problemy. ), A cały post jest posypany subtelnie błędnymi informacjami, które zatruwają każdego początkującego programistę.
MULTILINE
trybie zachowanie^
i$
zależy od definicji „terminatora linii”. Java uważa\r\n
,\n
,\r
,\u0085
,\u2028
,\u2029
aby być linia terminatora, gdzie\r\n
sekwencja jest uważany atomowej. JavaScript uważa\n
,\r
,\u2028
,\u2029
być terminatory linii. Ruby uważa tylko\n
za terminator linii.split
funkcja może mieć różną semantykę w różnych językach dla przypadków narożnych. Python nie dzieli się na puste dopasowania, Java usuwa końcowe ciągi znaków (chyba że określisz limit ujemny), JavaScript nie dzieli się na dopasowanie pustych ciągów o indeksie 0.źródło
Skrypt Bash
To dzieli ciąg według nowego wiersza. Jeśli powtórzysz echo
$new_string
, zauważysz, że zastąpił on nową linię separatorami tablic.Przykładowe dane wyjściowe:
źródło
Jawa
To nie czyta z pliku. Używane są wyrażenia regularne. Kod zakłada, że odczytany ciąg ma znak „\ n” wskazujący nowy wiersz. Liczby 1,2,3,4 służą do oznaczenia podziału.
źródło
DO#
źródło
Nie określasz, czy „nowa linia”, na którą chcesz podzielić ciąg, rozróżnia małe i duże litery. Zakładam, że nieczuły.
źródło
Stary, w Powershell jest to bardzo łatwe.
Po prostu weź swój ciąg w następujący sposób:
Następnie zapętlaj losowy ascii, aż łańcuch zostanie podzielony na dwa w następujący sposób:
ostatecznie powinieneś otrzymać podzielony ciąg, który możesz wypisać w następujący sposób:
Wydajność:
źródło
Php
Oto jak dzielisz strunę. Czy to nie takie proste?
Wszystko, co musisz teraz zrobić, to napisać funkcję
Spliter()
źródło
specyficzne dla bash
Świetna robota na bash !
Tak, podział łańcucha można wykonać w naprawdę prosty sposób:
Najpierw musisz zainicjować zmienną, której będziesz używać do przechowywania podzielonego wyniku:
Teraz, ponieważ każda linia jest oddzielona dwoma separatorami, początkiem lub końcem ciągu, będziesz potrzebować zmiennej do przechowywania pierwszego
Ok, teraz możesz wyszukać separator i zapisać swoje linie za pomocą pętli . Ponieważ bash nie mógł działać z wartością binarną, możesz użyć narzędzia takiego jak
od
praca z wartościami szesnastkowymi, na przykład:Teraz mamy podzielony ciąg przechowywany w zmiennej
lines
:Że możemy wydrukować za pomocą:
Umieszczenie tego wszystkiego w jednym skrypcie:
Spowoduje to wydrukowanie:
Nowoczesne bash
Ale stosując nowoczesną implementację bash , możesz przechowywać znaki kontrolne, takie jak nowa linia, w zmiennej, a nawet je testować:
bash golf
Ale jeśli nie zależy Ci na czytelności, możesz napisać skondensowany skrypt w następujący sposób:
Skrypt w golfa może wyglądać następująco:
i da ten sam efekt: Łańcuch podziału pierwszego wiersza i zapisz go w tablicy o nazwie wiersze . Drugi wiersz wypisze każdy element „ linii ” macierzy , a po nim nowy wiersz .
konsola bash + vt
Ale ponieważ wiele osób korzysta z konsoli tekstowej opartej na standardzie ANSI VT , możesz użyć zachowań VT konsoli i napisać to jeszcze raz:
da taki sam wynik.
źródło