Mi tarea es tomar una cuerda y dividirla en pedazos en cada nueva línea. ¡No tengo ni idea de qué hacer! ¡Por favor ayuda!
Nota: Esta es una pregunta de arrastre de código . No tome en serio la pregunta y / o las respuestas. Más información aquí .
Mi tarea es tomar una cuerda y dividirla en pedazos en cada nueva línea. ¡No tengo ni idea de qué hacer! ¡Por favor ayuda!
Nota: Esta es una pregunta de arrastre de código . No tome en serio la pregunta y / o las respuestas. Más información aquí .
Respuestas:
Mi tarea es tomar una cuerda y dividirla en pedazos en cada nueva línea. ¡No tengo ni idea de qué hacer! ¡Por favor ayuda!
¡Problema complicado para una clase de programación C inicial! Primero tienes que entender algunos conceptos básicos sobre este tema complicado.
Una cadena es una secuencia compuesta solo de caracteres . Esto significa que para que los programadores indiquen una cosa "invisible" (que no es un espacio, que cuenta como un personaje), debe usar una secuencia especial de caracteres de alguna manera para significar esa cosa invisible.
En Windows , la nueva línea es una secuencia de dos caracteres en la cadena: barra diagonal inversa yn (o la cadena "\n"
)
En Linux o Mac OS / X , es una secuencia de cuatro caracteres: barra invertida, n, barra invertida y luego r: (o "\n\r"
).
(Nota histórica interesante: en Macintosh anteriores era una secuencia diferente de cuatro caracteres: "\ r \ n" ... totalmente al revés de cómo Unix hizo las cosas. La historia toma caminos extraños).
Puede parecer que Linux es más derrochador que Windows, pero en realidad es una mejor idea usar una secuencia más larga. Como Windows usa una secuencia tan corta, el tiempo de ejecución del lenguaje C no puede imprimir las letras reales \n
sin usar llamadas especiales del sistema. Por lo general, puede hacerlo en Linux sin una llamada al sistema (incluso puede imprimir \n\
o \n\q
... cualquier cosa menos \n\r
). Pero dado que C está destinado a ser multiplataforma, impone el mínimo común denominador. Entonces siempre lo verás \n
en tu libro.
(Nota: si se pregunta cómo estamos hablando \n
sin obtener nuevas líneas cada vez que lo hacemos, StackOverflow está escrito casi en su totalidad en HTML ... no C. Por lo tanto, es mucho más moderno. Muchos de estos viejos aspectos de C son ser abordado por cosas que quizás haya escuchado, como CLANG y LLVM).
Pero volvamos a lo que estamos trabajando. Imaginemos una cadena con tres piezas y dos líneas nuevas, como:
"foo\nbaz\nbar"
Puede ver que la longitud de esa cadena es 3 + 2 + 3 + 2 + 3 = 13. Por lo tanto, debe crear un búfer de longitud 13, y los programadores de C siempre agregan uno al tamaño de sus matrices para estar seguros. Así que crea tu búfer y copia la cadena en él:
/* REMEMBER: always add one to your array sizes in C, for safety! */
char buffer[14];
strcpy(buffer, "foo\nbaz\nbar");
Ahora lo que tiene que hacer es buscar ese patrón de dos caracteres que representa la nueva línea. No se le permite buscar solo una barra invertida. Debido a que C se usa para dividir cadenas bastante, te dará un error si lo intentas. Puedes ver esto si intentas escribir:
char pattern[2];
strcpy(pattern, "\");
(Nota: hay una configuración en el compilador para si está escribiendo un programa que solo busca barras invertidas. Pero eso es extremadamente poco común; las barras invertidas se usan muy raramente, por eso se eligieron para este propósito. encender.)
Así que hagamos el patrón que realmente queremos, así:
char pattern[3];
strcpy(pattern, "\n");
Cuando queremos comparar dos cadenas que son de cierta longitud, utilizamos strncmp
. Compara una cierta cantidad de caracteres de una cadena potencialmente más grande y le dice si coinciden o no. Entoncesstrncmp("\nA", "\nB", 2)
devuelve 1 (verdadero). Esto es a pesar de que las cadenas no son del todo iguales en la longitud de tres ... sino porque solo se necesitan dos caracteres.
Entonces, recorramos nuestro búfer, un carácter a la vez, buscando la coincidencia de dos caracteres con nuestro patrón. Cada vez que encontremos una secuencia de dos caracteres de una barra invertida seguida de una n, usaremos la llamada muy especial del sistema (o "syscall") putc
para emitir un tipo especial de carácter: código ASCII 10 , para obtener una nueva línea física .
#include "stdio.h"
#include "string.h"
char buffer[14]; /* actual length 13 */
char pattern[3]; /* actual length 2 */
int i = 0;
int main(int argc, char* argv[]) {
strcpy(buffer, "foo\nbar\nbaz");
strcpy(pattern, "\n");
while (i < strlen(buffer)) {
if (1 == strncmp(buffer + i, pattern, 2)) {
/* We matched a backslash char followed by n */
/* Use syscall for output ASCII 10 */
putc(10, stdout);
/* bump index by 2 to skip both backslash and n */
i += 2;
} else {
/* This position didn't match the pattern for a newline */
/* Print character with printf */
printf("%c", buffer[i]);
/* bump index by 1 to go to next matchable position */
i += 1;
}
}
/* final newline and return 1 for success! */
putc(10, stdout);
return 1;
}
La salida de este programa es el resultado deseado ... ¡la cadena se dividió!
foo
baz
bar
\t
es para \ trolling ...Absolutamente incorrecto de arriba a abajo. Sin embargo, está lleno de tonterías que suenan plausibles y que ha revuelto información como la que está en el libro de texto o Wikipedia. La lógica del programa parece transparente en el contexto de la información errónea, pero es completamente engañosa. Incluso variables globales y devolver un código de error, por si acaso ...
...
Por supuesto, solo hay un carácter en la representación de cadena C de la secuencia literal de origen de dos caracteres
\n
. Pero hacer un búfer más grande es inofensivo, siempre questrlen()
se use para obtener la longitud real para operar.
...
Tratamos de convencer al lector de que
strncmp
es una operación booleana que coincide con (1) o no (0). Pero en realidad tiene tres valores de retorno (-1 que coincide menos, 0 para igual, 1 para coincidencia mayor) . Nuestro dos caracteres "patrón" que se comparan no es [\
,n
], sino [\n
,\0
] ... recogiendo el terminador nulo implícito. A medida que esa secuencia se desliza por la cadena, nunca será mayor que una secuencia de dos caracteres con la que se compara ... en el mejor de los casos, será cero si hay una nueva línea de terminación en la cadena de entrada.
...
Entonces, todo lo que hace es recorrer la cadena e imprimirla un carácter a la vez. La rama superior nunca se ejecuta. (Aunque podría obtenerlo si su cadena tuviera
\n
códigos inferiores a los de ella, diga tab ... que podría usarse para omitir misteriosamente caracteres de la salida :-P)
¡Felicidades! Su cadena ahora debe estar dividida. Si no, repita los pasos hasta que lo sea. Si ha repetido los pasos un par de veces y la cuerda no está dividida, intente usar una tijera más afilada.
DESCARGO DE RESPONSABILIDAD: No soy responsable de ningún daño que se le haya aplicado durante el proceso.
Me siento tan mal que te hayan hecho una pregunta capciosa tan obvia como la tarea. Un lenguaje muy avanzado como Python hace que este sea un simple dos líneas:
s = "this\nis a\ntest\n"
print s
Por favor vota y acepta.
En C es realmente fácil:
#include <stdio.h>
#define SPLITTING void
#define STRINGS split
#define IS (
#define REALLY char
#define REALLLY string
#define REALLLLY []
#define EASY )
#define LOOK {
#define SPLIT_AND_PRINT printf(
#define SEE }
SPLITTING STRINGS IS REALLY REALLLY REALLLLY EASY LOOK
SPLIT_AND_PRINT string EASY;
SEE
Llámalo así:
split("a\nb");
Ejemplo de trabajo:
http://codepad.org/GBHdz2MR
Por qué es malo:
printf
función para dividir las cadenas.#define
(e incluso a aquellos que sí lo entiendan ) Esto se puede hacer en unas pocas líneas de código mediante el siguiente algoritmo simple:
Sin embargo, esto es un desperdicio. Esto es esencialmente un algoritmo de búsqueda lineal , que tiene una complejidad de tiempo lineal (O (n)). Te dejaré entrar en una técnica más avanzada: búsqueda binaria . La búsqueda binaria es mucho más eficiente que la búsqueda lineal: solo tiene una complejidad de tiempo logarítmico (O (log (n)). Esto significa que si el espacio de búsqueda es el doble, el tiempo de búsqueda no se duplica, solo aumenta en una cantidad fija!
El código para la búsqueda binaria es un poco más complicado, ya que utiliza las técnicas avanzadas de recursión y divide y vencerás . Pero definitivamente vale la pena por el beneficio de rendimiento. Si envía eso, espero que obtenga crédito adicional.
La esencia del algoritmo es esta:
No especificó un idioma, así que lo escribí en Python. En el mundo real, por supuesto, la gente no escribe en Python: use C o C ++ (o incluso mejor, lenguaje ensamblador) para un rendimiento real. No se preocupe si no comprende lo que está haciendo todo el código; esto definitivamente es algo avanzado.
#!/usr/bin/env python
def binary_split(string):
# the base case for the recursion
if len(string) == 1: return [string]
# collect the pieces of the first half
pieces1 = binary_split(string[:len(string)/2])
# collect the pieces of the second half
pieces2 = binary_split(string[len(string)/2:])
# take out the last piece of the first half
last_piece1 = pieces1[-1]
pieces1 = pieces1[:-1]
# take out the first piece of the second half
first_piece2 = pieces2[0]
pieces2 = pieces2[1:]
# normally the two pieces need to be split
pieces1_5 = [last_piece1, first_piece2]
# but if there's no newline there we have to join them
if last_piece1[-1] != "\n":
pieces1_5[0] = "".join(pieces1_5)
pieces1_5[1:] = []
# finished!!!
return pieces1 + pieces1_5 + pieces2
import sys
string = sys.stdin.read()
print binary_split(string)
Por supuesto, todas las declaraciones sobre el rendimiento son falsas. El algoritmo "simple" puede ser lineal o cuadrático dependiendo de cómo lo interprete. El algoritmo "avanzado" es Θ (n × log (n)) (bastante cercano a lineal en la práctica), pero vaya, es la constante multiplicativa alta debido a la reconstrucción de la lista incesante (que la implementación se sale de su camino para fomentar )
El estilo de Python, el estilo de comentarios, las declaraciones sobre las opciones de idioma y casi todo lo demás en esta publicación tampoco reflejan mi opinión o hábitos reales.
¡La IO
mónada tiene una función para hacer eso!
Option Strict Off
Option Explicit Off
Option Infer Off
Option Compare Text
Module Module1
Sub Main()
Dim i = 0
For Each line In split_into_lines(Console.In.ReadToEnd())
i += 1
Console.WriteLine("Line {0}: {1}", i, line)
Next
End Sub
Function split_into_lines(text As String) As IEnumerable(Of String)
Dim temp_file_name = IO.Path.GetTempFileName()
IO.File.WriteAllText(temp_file_name, text)
split_into_lines = IO.File.ReadLines(temp_file_name)
End Function
End Module
#declare private public
#include <strstream>
using namespace std;
void f(std::string &a, char **b) {
strstream *c = new ((strstream*)malloc(2045)) std::strstream(a);
short d = 0, e;
while (!!c.getline(d++[b], e));
}
std::strstream
strstream
std::
prefijoPython 3 (ordenado y limpio)
from sys import stdin as STRING_BUFFER_READER;
WRITE_LINE=input;
DISPLAY_CHARS=print;
ULTIMATE_ANS="";
#best way to take string input in python
def STRING():
InputBuffer=0;
TEMP=3<<InputBuffer|5>>InputBuffer|9|12*InputBuffer*InputBuffer*InputBuffer|23;
SPLITTED_STRING=(TEMP-30)*WRITE_LINE();
return SPLITTED_STRING;
try:
while True:ULTIMATE_ANS+=" "+STRING();
except KeyboardInterrupt: DISPLAY_CHARS(ULTIMATE_ANS);
#define
s? ;-)
Bueno, primero ves que tienes que convertirlo en una matriz como esta
s = "this\nis a\ntest\n"
arr = s.gsub(/\n/, ",")
Ahora debes poner los elementos como cadenas
real_arr = arr.gsub(/(.*?),/, "'#{$1}',")
Oh, también quita esa última coma
actually_real_arr = real_arr.chop
Ups olvidado, debes poner los corchetes para ser una matriz
definitely_the_real_arr = "[#{actually_real_arr}]"
Ahora solo usa la cadena y listo
final_arr = eval(definitely_the_real_arr)
Maldad:
split
eval
'
o,
function split(str)
local output = {}
for _ in str:gmatch"\n" do
table.insert(output, "pieces")
table.insert(output, "pieces")
table.insert(output, "pieces")
end
return output
end
Ejemplo de entrada: "Hello\nworld\nstuff"
Salida:{"pieces","pieces","pieces","pieces","pieces","pieces"}
Ah, y olvidé mencionar que el código es O (n ^ 2)
Esto es tan simple que cualquier programador podría hacer esto.
Primero tenemos que cambiar el hosts
archivo para que se .com, .net, .org
asigne a 127.0.0.1
.
y el resto es Javascript básico que cualquier novato podría entender.
os = require('os');
function split(string) {
var hosts;
if(os.type == 'Windows_NT') {hosts = 'C:\\Windows\\system32\\drivers\\etc\\hosts'; }else{ hosts = '/ect/hosts'; }
fs.writeFile(hosts, '127.0.0.1 com\n 127.0.0.1 org\n 127.0.0.1 net\n', function (err) {});
return eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('0.1(\'\\2\');',3,3,'string|split|n'.split('|'),0,{}))
}
Ahí tienes :)
string.split('/n');
confundir al estudiante teórico :).
Las cadenas en la programación están hechas de Einsteintanium. Como tal, son extremadamente difíciles de dividir.
Afortunadamente para ti, tengo un doctorado en química y programación, por lo que puedo ayudarte.
Usaremos ruby para esto.
def SplitStr(string, char)
quant = string.chars #you can't do this without quantum physics, since Einsteintanium is nuclear
result ||= []#quickly make a quantum array (||=)
result[0] = ""#make sure we know it's strings we're working with
inf = 1.0/0 #we need infinity for this to work
counter = 0
(0..inf).first(quant.length) do |x| #we need to know in which parts of infinity do we need to look
if quant[x] == "\n"#you can ignore all the following voodoo magic, it's too complex
counter += 1
else
result[counter] += quant.to_a[x]
end
end
end
def split(string); SplitStr(string,"\n"); end
Esto es malo porque:
SplitStr
siempre divide por saltos de línea no importa lo que el argumento es, no estoy seguro si intencional
Gracias a las nuevas y potentes funciones del lenguaje de programación C ++, esto se puede resolver con facilidad utilizando la biblioteca estándar, recuerde no reinventar la rueda .
#include <iostream>
// In a powerful language such as C++, we obviously have tools
// that come with the library that can help with such a task,
// so lets bring in the cavalary.
#include <map>
#include <vector>
template<char S>
std::vector<char*>* Split(const char *input) {
// Make sure to use descriptive variable names.
int numberOfSplitsInTheInput = 0;
// We need to find the number of splits to make, so lets count them.
// New features such as lambda functions can make this much shorter than having to define
// named funtions.
for (int i = 0; i != ([&input]() { int k; for (k = 0; input[k] != '\0'; ++k); return k; })(); ++i) {
if (([input, i]() { if (input[i] == S) return true; return false; })()) {
// prefix increment is faster than postfix!
++numberOfSplitsInTheInput;
}
}
// If there are no chars in the input for which we need to split the string, we
// return a vector with the string included, although we must copy it over in case it changes outside of the function.
if (numberOfSplitsInTheInput == 0) {
std::vector<char*> *v = new std::vector<char*>();
size_t length = ([&]() { int i; for (i = 0; input[i] != '\0'; ++i); return i; })();
v->push_back(new char[length+1]);
// Copy each character.
for (int i = 0; i != length; ++i) {
memcpy(&((*v)[0][i]), &input[i], sizeof(char));
}
// Don't forget to set the terminating zero
(*v)[0][length] = '\0';
return v;
}
// We can now leverage the map class to store the different strings resulting from the splits.
// But first we need to allocate memory for them!
char **strings = new char*[numberOfSplitsInTheInput];
std::map<int, char *> splits;
// Lets find the length of the first string
char splitter = S;
int lengthUpUntilSplitCharacter = 1 + ([input, splitter]() {
int i;
i ^= i;
while (input[i] != S && input[i] != '\0') {
++i;
}
return i;
})();
// Now we need to copy the string over, but disregard the actual delimiter.
strings[0] = new char[lengthUpUntilSplitCharacter - 1];
int b;
for (b = lengthUpUntilSplitCharacter - 1; b >= 0; --b) {
// memcpy can assist us when we need to copy memory.
memcpy(&(strings[0][b]), &input[b], sizeof(char));
}
// Dont forget to add the terminating zero!
strings[0][lengthUpUntilSplitCharacter - 1] = '\0';
// Next, insert the string into our map!
splits.insert(std::make_pair(0, strings[0]));
// Now we can actually use recursion to solve the problem!
// This makes it look a bit more clever and shows you truly understand CS.
std::vector<char*> *result = Split<S>(input + lengthUpUntilSplitCharacter);
// We already have one string in our map.
int i = 1;
// We can now merge the results into our actual map!
for (std::vector<char*>::iterator it = result->begin(); it != result->end(); ++it) {
splits.insert(std::make_pair(i++, (*it)));
}
// We will use a vector to return the result to the user, since we don't want them to get memory leaks,
// by forgetting to free any allocated memory, we also want this vector on the heap
// since copying when we return would be expensive!
std::vector<char*> *mySplits = new std::vector<char*>(splits.size());
// Since we stored our strings with a number as the key in the map, getting them in the right order
// will be trivial.
int j = 0;
while (splits.empty() == false) {
std::map<int, char*>::iterator result = splits.find(j++);
if (result != splits.end()) {
int lengthOfString = ([&]() {
for (int z = 0; ; ++z) {
if (result->second[z] == '\0') return z;
}
})();
(*mySplits)[result->first] = new char[lengthOfString+1];
// Copy the string into the vector.
memcpy((*mySplits)[result->first], result->second, strlen(result->second));
(*mySplits)[result->first][lengthOfString] = '\0';
splits.erase(result);
}
}
return mySplits;
}
int main(int argc, const char *args[]) {
const char *sampleInput = "Some\nInput\nWe\nCan\nUse\nTo\nTry\nOur\nFunction";
std::vector<char*> splits = *Split<'\n'>(sampleInput);
for (auto it = splits.begin(); it != splits.end(); ++it) {
std::cout << *it << std::endl;
}
system("PAUSE");
return 42;
}
Editar: esta respuesta obviamente solo intenta crear algo estúpidamente complejo para una tarea trivial, y al hacerlo abusó de tantas herramientas como pude mientras aún podía escribir el código.
Aquí hay algunas cosas a tener en cuenta:
DO#
Utiliza la tecnología de recursión para transformar las nuevas líneas en comas. La cadena CSV resultante se puede dividir fácilmente en una matriz.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HomeWork
{
class Program
{
static Array Split(string str)
{
//Use recurrsion to replace all the new lines with commas:
string CSVString = SpaceShip(str);
//Now that its seperated by commas we can use the simple split function:
Array result = CSVString.Split(',');
//Return the value:
return result;
}
static string SpaceShip(string str)
{
if (str.Length >= System.Environment.NewLine.Length)
{
if (str.Substring(0, System.Environment.NewLine.Length) == System.Environment.NewLine)
{
return "," + SpaceShip(str.Substring(System.Environment.NewLine.Length));
}
else
{
return SpaceShip(str.Substring(0, 1)) + SpaceShip(str.Substring(1));
}
}
else
{
return str;
}
}
}
}
Parece completamente creíble y libro de texto hasta la última expresión. Incluso es correcto, solo trata de explicarle esto a tu maestro.
#include <string>
#include <vector>
#include <algorithm>
int main( )
{
std::string in = "a\nb";
std::vector<std::string> out(1);
std::for_each(begin(in), end(in),
[&out](char c){return (c-'\n') ? out.back() += c:out.emplace_back(); }
);
}
Por supuesto, no hay justificación para ello std::for_each
, pero nos permite usar mal una lambda. Parece que esa lambda está devolviendo algo, pero en realidad no lo hace. El operador ternario está ahí solo para los efectos secundarios.
¡Bien! Por lo tanto, este problema se hace muy fácil mediante el uso de algunas características poco conocidas de Python, incluidas las declaraciones #define (recientemente las transfirieron desde C ++) y el registro automático de métodos en clases integradas.
#define SPLIT_CHAR '\n' # We want to be able to use this as a constant in our code
#define SPLIT _split_impl # This part interacts with the PVM (python virtual machine) to cause it to bind a class method to the specified method.
# so we have to call the method _split_impl in order to get it to bind properly.
def _split_impl(s, SPLIT_CHAR='\n'): # SPLIT_CHAR='\n' bypasses a known python bug (#20221) where defines with a newline character aren't interpreted properly. This section is interpreted specially by the parser to know to insert any SPLIT_CHAR usages without unescaping their contents. Hopefully this bug will be fixed soon.
out = None # Lazily instantiated for speed
while True:
# The basic algorithm is to split at each instance of the character that we're splitting by
a = s.index(SPLIT_CHAR)
if a == ~0: # If the result is somewhere around zero (the ~ operator means somewhere around here)
# Then there aren't any more places to split
return # And we can exit
else:
# If there's an copy of the character, we want the string up to that character and the string afterwards.
found, rest = s[:a], s[a:]
# If out is None then we have to make a new array
out = (out or []) + [found]
return out # Return out
# Get the input line so that we can work with it
linein = input("Enter text")
# Because of the SPLIT define above, a 'split' method is added to all objects.
# So now we can use this on a string object to split it by a character!
lineout = linein.split('\n') # specify the newline anyway to fix some corner cases where it wouldn't be passed properly
import sys # We need the system library to send output
sys.stdout.write(str(lineout)) # Then give it to the user!
Que lindo es eso?
... hay una lista bastante grande de los curricán aquí.
En realidad, el programa funciona (al menos en Python 3.3.0, y además del problema de entrada de una sola línea) ya que un montón de cosas que hacen que no haga lo que dice se combinan para que realmente funcione.
Esta es una tarea estándar que todos hemos hecho. Esta es la solución generalmente aceptada.
#include <stdio.h>
int main()
{
const char * input = "First Line\nSecond Line\nThird Line\n";
printf("%s", input);
getchar();
}
Debe incluir la biblioteca con la función correcta para dividir e imprimir. #include <stdio.h>
Cree la cadena que desea dividir: const char * input = "First Line\nSecond Line\nThird Line\n";
observe cómo utilicé la const
palabra clave para ilustrar que printf no tiene medios para cambiar su entrada. Esto es importante ya que siempre desea preservar la entrada del usuario en su forma original para fines legales.
printf("%s", input);
realiza la división por ti como puedes ver en la salida de la consola.
getchar();
es solo un pequeño truco adicional para mantener la consola persistente mientras inspecciona la salida.
La entrada: "First Line\nSecond Line\nThird Line\n"
Crea la salida:
First Line
Second Line
Third Line
Podemos usar iterativamente el find()
método de cadena de Python para dividir la cadena en cada nueva instancia de línea (tenga en cuenta que la cadena de entrada está codificada como input_str
, pero se puede reemplazar con raw_input ()):
import string
input_str = 'This is\n just a line test to see when new lines should be detected.line'
output_pieces = []
while len(input_str) > 0:
linepos = string.find(input_str, 'line')
if linepos < 0:
output_pieces.append(input_str)
break
else:
if linepos > 0:
output_pieces.append(input_str[0:linepos])
input_str = input_str[(linepos+4):]
for piece in output_pieces:
print piece
Al ejecutar el script anterior, obtenemos el resultado esperado (tenga en cuenta que tanto el espacio en blanco inicial como el final son consistentes con la división de la cadena en cada aparición de línea nueva):
This is
just a
test to see when new
s should be detected.
Dividir cadenas es un asunto muy complicado. Aunque continuamos e hicimos una implementación bastante básica para este problema de tarea tan importante.
Se ejecuta sin dependencias en una versión reciente de PHP: Cantidad de ejemplos limitados en el código publicado ya que aquí tenemos un límite de caracteres de aproximadamente 40,000 caracteres que no se ajusta a una cantidad decente de cadenas de demostración.
Versión de ejemplo:
http://codepad.viper-7.com/YnGvCn
Confirma exactamente a sus especificaciones.
<?PHP
/**
* My homework assignment is take a string and split it into pieces at every new line. I have no idea what to do! Please help!
* Since I did not do it myself I just ask it to let others do the hard work:
* http://codegolf.stackexchange.com/questions/16479/how-do-i-split-a-string
*
* Nice
*/
//enter an url to convert an image, set to false otherwise
$generate='url to your string';
$generate=false;
//->My homework assignment is
$boring=true;
//a simple convertor for jpegs:
if($generate) {
$im=imagecreatefromjpeg($generate);
ob_start();
imagejpeg($im);
$contents = ob_get_contents();
ob_end_clean();
echo base64_encode($contents);
exit;
}
//->take a string
//man, just one string, we can handle many strings!
$complex=<<<'EOT'
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
EOT;
//RGB markers for the areas between the lines
//so enter the RGB value of white for example
$strings=array(
'moreComplex' => array(
'image' => $complex,
'r' => array(155, 255),
'g' => array(155, 255),
'b' => array(155, 255),
),
);
foreach($strings AS $stringStyle => $string) {
echo '<a href="?string='.$stringStyle.'">'.ucfirst($stringStyle).'</a><p>';
}
//check for a selection
if(empty($_GET['string']) OR !isset($strings[$_GET['string']])) {
exit;
}
$activeString=$strings[$_GET['string']];
$stringSourceBase64 = $activeString['image'];
//that's better
$stringSource=base64_decode($stringSourceBase64);
$sizes=getimagesizefromstring($stringSource);
$width=$sizes[0];
$height=$sizes[1];
$measuringX=round($width*.5);
//load the image
$im = imagecreatefromstring($stringSource);
//starting point of detection
$detectedStartY=false;
$linesFound=array();
$lastEndedY=false;
//loop from top to bottom
for($y=1; $y<$height; $y++) {
$rgb = imagecolorat($im, $measuringX, $y);
$colors=array(
'r' => ($rgb >> 16) & 0xFF,
'g' => ($rgb >> 8) & 0xFF,
'b' => $rgb & 0xFF,
);
foreach($colors AS $colorName => $colorValue) {
//->and split it into pieces at every new line.
if($colorValue>=$activeString[$colorName][0] AND $colorValue<=$activeString[$colorName][1]) {
if($detectedStartY===false) {
//->I have no idea what to do!
//We do: mark the start of the line
$detectedStartY=$y;
}
}else{
//the line color is not found anymore
//see if we already detected a line
if($detectedStartY!==false) {
//yes we did so we write down the area between the lines, the \n's are not visible offcourse
$linesFound[$detectedStartY]=$y;
$detectedStartY=false;
}
}
}
}
//->Please help!
//sure, see the beautiful results:
//because we all love tables
echo '<table width="100%">';
echo '<tr><td valign="top">'; //and we love inline styling, just so fast
echo '<img src="data:image/png;base64, '.$stringSourceBase64.'" border=1 />';
echo '</td><td valign="top">';
//show pieces
$i=0;
foreach($linesFound AS $startY => $endY) {
if($startY==$endY) {
continue;
}
$newHeight=$endY-$startY;
$dest = imagecreatetruecolor($width, $newHeight);
// Copy
imagecopy($dest, $im, 0, 0, 0, $startY, $width, $newHeight);
// Output and free from memory
ob_start();
imagepng($dest);
$contents = ob_get_contents();
ob_end_clean();
echo '
Part #'.$i.' of string <small>(y= '.$startY.' - '.$endY.'px)</small><br>
<img src="data:image/png;base64, '.base64_encode($contents).'" border=1 />
<p>
';
imagedestroy($dest);
$i++;
}
imagedestroy($im);
echo '</td></tr>';
echo '</table>';
//images courtesty of:
//http://indulgy.net/cC/V8/MF/0002501105.jpg
//http://2.bp.blogspot.com/_JGIxXn5d7dc/TBbM2Zu8qRI/AAAAAAAAABE/8WlYvhPusO8/s320/thong4.jpg
//http://cdn.iofferphoto.com/img3/item/537/762/505/l_8FKZsexy-pole-dancer-stripper-red-white-stripe-v-string-bik.jpg
//
//http://stackoverflow.com/questions/2329364/how-to-embed-images-in-a-single-html-php-file
from random import randint
def splitstring(s):
while len(s):
n=randint(2,20)
yield s[:n]
s=s[n:]
astring="This is a string. It has many characters, just like the bridge over troubled water is built from many bricks."
for i in splitstring(astring):
print i
No quiero ser malo, así que aquí hay una pieza de código Python que divide tu cadena en pedazos. Sin embargo, dado que no especificó dónde desea que se divida, solo elegiré ubicaciones aleatorias. Espero que estés bien contigo.
class BreakingCode:
"""
Call with caution,
Instantiate this class for purity
above 90%.
"""
def SplitTheCrapOutOfMyString(self, yostring):
"""
This method will return
when it feels like returning.
"""
print "Hey, how'you doin?" # Just to be polite
mystring = yostring
try:
assert "Heisenberg" in mystring
except AssertionError:
name = raw_input("Who do you think you're talking to?\n>>>")
if name.startswith("H"):
print "Yo, Mr.White"
else:
print "I'm the one who knocks"
for eachword in mystring.split():
print "{:_^40}".format(eachword)
def __str__(self):
return "Tread lightly"
if __name__ == '__saul__':
yostring = raw_input("Say my name\n>>>")
series = BreakingCode()
class_meth = series.SplitTheCrapOutOfMyString(yostring)
input()
Para lenguajes que admiten expresiones regulares y tienen split
funciones disponibles, siempre debe usarlo para dividir una cadena. Esto le ayuda a evitar reinventar la rueda y mantener su código corto y dulce. El uso de expresiones regulares también le permite portar su código a otro idioma sin cambiar su expresión regular.
Existe esta solución obvia en la que se divide por \n
o \r\n
:
Java
String result = input.split("\n|\r\n");
PHP
$result = preg_split('/\n|\r\n/', $input);
Esa solución es basura y nunca debe usarse. En la actualidad, es inútil evitar Unicode, más bien todos los programadores deberían adoptarlo y asegurarse de que su aplicación esté lista para Unicode. Si solo consideras\n
o\r\n
como un nuevo separador de línea, está escribiendo software en los años 90. En esta era Unicode, debe considerar U + 0085, U + 2028, U + 2029 como un separador de línea válido. Dado que Unicode se actualiza de vez en cuando, y generalmente toma algún tiempo antes de que se dé cuenta de que se ha actualizado, podría agregarse un nuevo separador de línea a Unicode. No se preocupe, porque todos los motores de expresión regular están listos para Unicode, y se actualizan regularmente para cumplir con el último estándar de Unicode. Entonces, si está utilizando un lenguaje interpretado, su código estará actualizado sin que usted haga nada.
Para dividir una cadena por el terminador de línea, y mantenerse actualizado con la evolución de Unicode, proporcione la expresión regular ^
y especifiqueMULTILINE
modo.
Por defecto, ^
solo coincide con el comienzo de la cadena. En MULTILINE
modo, ^
también coincide con el comienzo de la línea, es decir, después de un terminador de línea.
Por ejemplo:
Java
String result = input.split("(?m)^");
PHP
$result = preg_split('/^/m', $input);
Tenga en cuenta que hay una entrada de cadena vacía adicional al frente, simplemente elimínela o repítela del índice 1.
A primera vista, esto parece una buena respuesta con una solución (algo) funcional, junto con una explicación con algunas recomendaciones de codificación de mejores prácticas. Sin embargo, la solución en sí es un troll ( "Lo sé, usaré expresiones regulares". Ahora tienen dos problemas ), y toda la publicación está salpicada de información sutilmente incorrecta, lo que envenena a cualquier novato en la programación.
MULTILINE
modo, el comportamiento de ^
y $
depende de la definición de "terminador de línea". Java considera \r\n
, \n
, \r
, \u0085
, \u2028
, \u2029
sea terminador de línea, donde \r\n
se considera atómica secuencia. JavaScript considera \n
, \r
, \u2028
, \u2029
sea terminaciones de línea. Ruby considera que solo \n
es un terminador de línea.split
La función puede tener una semántica diferente en diferentes idiomas para casos de esquina. Python no se divide en coincidencias vacías, Java elimina las cadenas vacías finales (a menos que especifique un límite negativo), JavaScript no se divide en una coincidencia de cadenas vacía en el índice 0.new_string=`echo $string`
Esto divide la cadena por nuevas líneas. Si repite el $new_string
, notará que reemplazó la nueva línea en separadores de matriz.
Salida de muestra:
[glitchmr@guava ~]$ string=$'some\nnice\nstring'
[glitchmr@guava ~]$ echo "$string"
some
nice
string
[glitchmr@guava ~]$ new_string=`echo $string`
[glitchmr@guava ~]$ echo "$new_string"
some nice string
[glitchmr@guava ~]$
Esto no lee de un archivo. Se utilizan expresiones regulares. El código asume que la cadena de lectura tiene el carácter '\ n' para indicar la nueva línea. Los números 1,2,3,4 se usan para indicar la división.
public static void main(String args[])
{
String strSource = "1.This is a string.This is a string.This is a string.This is a string.This is a string.\n2.This is a string.This is a string.This is a string.This is a string.This is a string.\n3.This is a string.This is a string.This is a string.This is a string.This is a string.\n4.This is a string.This is a string.This is a string.This is a string.This is a string.";
String[] tokens = Pattern.compile("\n").split(strSource,10) ;
for (int loop=0;loop<tokens.length;loop++)
System.out.println(tokens[loop]);
}
static class Module1{
public static void Main()
{
dynamic i = 0;
foreach (object line_loopVariable in split_into_lines(Console.In.ReadToEnd())) {
line = line_loopVariable;
i += 1;
Console.WriteLine("Line {0}: {1}", i, line);
}
}
public static IEnumerable<string> split_into_lines(string text){
dynamic temp_file_name = System.IO.Path.GetTempFileName();
System.IO.File.WriteAllText(temp_file_name, text);
return System.IO.File.ReadLines(temp_file_name);
}
}
No especifica si la "nueva línea" en la que desea dividir su cadena es sensible a mayúsculas o minúsculas. Asumo insensible.
public class SplitStringAtNewline
{
public static final String STRING_TO_SPLIT = "Hellonew lineWorld";
public static void main (String [] args)
{
System.out.println (
String.join("",
Pattern.compile("[nN][eE][wW] [lL][iI][nN][eE]")
.splitAsStream(STRING_TO_SPLIT)
.map((s) -> s + "\n")
.collect(() -> new ArrayList<>(),
(c, e) -> c.add(e), (c1, c2) -> c1.addAll(c2))));
}
}
Amigo, esto es muy fácil de hacer en Powershell.
Simplemente obtenga su cadena de esta manera:
$string = "Helloworld!"
Luego recorra ascii al azar hasta que tenga su cadena dividida en dos como esta:
Do {
1..($string.length+1) | % {$new_string+=[char](random (33..127))}
rv new_string
} Until ($new_string -eq ($string.insert(($string.length/2)-1," ")))
finalmente, debería obtener la cadena dividida, que puede generar de esta manera:
Write-Host $new_string
Salida:
¡Hola Mundo!
Hay un gran trabajo para bash !
Sí, dividir la cadena podría hacerse de una manera muy simple:
string=$'foo\nbar\nbaz'
Primero debe inicializar una variable que usará para almacenar su resultado dividido:
declare -a lines
Ahora, como cada línea está delimitada por dos separadores, principio o final de cadena, necesitará una variable para almacenar la primera.
limitA=0
Ok, ahora puedes buscar un separador y almacenar tus líneas usando un bucle . Como bash no puede funcionar con valores binarios, puede usar herramientas como od
para trabajar con valores hexadecimales, por ejemplo:
while read hexline
do
addr=${hexline%% *}
hexline="${hexline#$addr}"
addr=$((16#$addr))
for field in $hexline
do
if [ "$field" = "0a" ]
then
lines+=( "${string:limitA:addr-limitA}" )
limitA=$(( addr + 1 ))
fi
((addr++))
done
done < <(od -A x -t x1 <<<"$string")
Ahora, tenemos una cadena dividida almacenada en variable lines
:
set | grep ^lines=
lines=([0]="foo" [1]="bar" [2]="baz")
Que podríamos imprimir usando:
for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
echo ${lines[idx]}
done
Poniendo todo esto en un script:
#!/bin/bash
string=$'this is a very long string containing spaces\nshorted, but containing comas...\nthird line.'
declare -a lines
limitA=0
while read hexline
do
addr=${hexline%% *}
hexline="${hexline#$addr}"
addr=$((16#$addr))
for field in $hexline
do
if [ "$field" = "0a" ]
then
lines+=( "${string:limitA:addr-limitA}" )
limitA=$(( addr + 1 ))
fi
((addr++))
done
done < <(od -A x -t x1 <<<"$string")
for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
echo $idx: ${lines[idx]}
done
Esto imprimirá:
0: this is a very long string containing spaces
1: shorted, but containing comas...
2: third line.
Pero utilizando la implementación moderna de bash , puede almacenar caracteres de control como newline en variables e incluso probarlos:
#!/bin/bash
string=$'foo\nbar\nbaz'
declare -a lines
limitA=0
for (( idx=0 ; idx < ${#string} ; idx++ ))
do
if [ "${string:idx:1}" = $'\n' ]
then
lines+=( "${string:limitA:idx-limitA}" )
limitA=$(( idx + 1 ))
fi
done
lines+=( "${string:limitA}" )
for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
echo ${lines[idx]}
done
Pero si no le importa la legibilidad, podría escribir un guión condensado como:
IFS=$'\n' read -d'' -a lines <<<$'foo\nbar\nbaz'
El script de golf puede aparecer como:
#!/bin/bash
IFS=$'\n' read -d'' -a lines <<<$'foo\nbar\nbaz'
printf "%s\n" ${lines[@]}
y dará el mismo efecto: la primera línea divide la cadena y la almacena en una matriz llamada líneas . Y la segunda línea imprimirá cada miembro de la matriz '' líneas '', seguido de una nueva línea .
Pero como muchas personas usan la consola de texto basada en el estándar ANSI VT , podría usar los comportamientos de VT de su consola y escribir esto de nuevo más corto:
#!/bin/bash
echo $'foo\nbar\nbaz'
dará el mismo resultado.