주어진 문자열에서 주어진 색인 주위의 단어를 선택하십시오


20

Windows에서 텍스트를 두 번 클릭하면 텍스트에서 커서 주위의 단어가 선택됩니다.

(이 기능은 더 복잡한 속성을 갖지만이 과제를 위해 구현할 필요는 없습니다.)

예를 들어에서 |커서를 사용하십시오 abc de|f ghi.

그런 다음 더블 클릭하면 하위 문자열 def이 선택됩니다.

입출력

문자열과 정수의 두 가지 입력이 제공됩니다.

당신의 작업은 정수로 지정된 색인 주위에 문자열의 단어 하위 문자열을 반환하는 것입니다.

지정된 색인에서 문자열의 문자 바로 이나 뒤에 커서가있을 수 있습니다 .

바로 전에 사용하는 경우 답을 지정하십시오.

사양 (사양)

인덱스가되어 보장 더 에지의 경우처럼되지 않도록, 단어 내부로 abc |def ghi또는 abc def| ghi.

문자열 에는 인쇄 가능한 ASCII 문자 포함 됩니다 (U + 0020에서 U + 007E까지).

"word"라는 단어는 정규식에 의해 정의되며 (?<!\w)\w+(?!\w), 여기서 "또는 밑줄을 포함하여 ASCII의 영숫자"로 \w정의됩니다 [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_].

인덱스는 1 인덱스 또는 0 인덱스가 될 수 있습니다 .

0 색인을 사용하는 경우 답변에 지정하십시오.

테스트 케이스

테스트 케이스는 1- 색인이며 커서는 지정된 색인 바로 뒤에 있습니다.

커서 위치는 데모 목적으로 만 사용되며 출력 할 필요는 없습니다.

string    index     output    cursor position
abc def   2         abc       ab|c def
abc def   5         def       abc d|ef
abc abc   2         abc       ab|c abc
ab cd ef  4         cd        ab c|d ef
ab   cd   6         cd        ab   c|d
ab!cd     1         ab        a|b!cd

2
문자열에 줄 바꿈이 포함될 수 있습니까?
orlp

@orlp 입력을 인쇄 가능한 ASCII로 제한하여 입력에 개행이 포함되지 않도록 챌린지를 편집했습니다.
FryAmTheEggman

테스트 케이스에는 공백 이외의 다른 구분 기호가 없습니다. 같은 단어는 we're어떻습니까?
orlp

2
무엇을 "ab...cd", 3반환 해야 합니까?
Titus

5
@Titus "인덱스가되어 보장 단어 내부로"
마틴 청산

답변:


10

V , 10, 9 7 바이트

À|diwVp

온라인으로 사용해보십시오!

이 답변은 1 기반 인덱싱을 사용합니다.

제목 에서 "문자열에서 주어진 색인 주위의 단어를 선택하십시오 "라고 정확히 말하면 더 짧을 수 있습니다 . 우린 할 수있어

À|viw

말 그대로 단어를 선택하지만 불행히도 출력을 전혀 변경하지 않습니다. 따라서 레지스터로 자르고 나머지 텍스트를 삭제 한 다음 레지스터를 다시 붙여 넣어서 작동하게하려면 약간의 해결 방법이 필요합니다.

설명:

À|          " Jump the position of argument 1
  diw       " (d)elete (i)nside this (w)ord.
     V      " Select this line
      p     " And replace it with the word we just deleted

5

C, 104 바이트

p[99];i,d;main(l){for(scanf("%d",&i);scanf("%[^a-zA-Z0-9_]%[a-zA-Z0-9_]%n",&d,&p,&l),i>l;i-=l);puts(p);}

stdin의 입력이 0 기반 인덱스, 공백 또는 개행, 문자열이 될 것으로 예상합니다. 단어의 최대 길이는 99 자입니다. 예 :

2 abc def

C와 perl이 문자열 기반의 도전에 묶여있는 것을 보는 것이 정말 좋습니다. :D
DJMcMayhem

입력 문자열이 100자를 초과 할 수 있습니까?
Leaky Nun

@LeakyNun 예, 한 단어는 100자를 초과 할 수 없습니다.
orlp

그 요구 사항을 답 안에 넣는 것 같습니까?
Leaky Nun

@DrGreenEggsandIronMan 너무 나쁘다 나는 공백으로 구분되어 있기 때문에 대답을 고쳐야했다 :(
orlp

4

C (gcc), 94 바이트

f(n,p)char*p;{for(p+=n-1;isalnum(*p)|*p==95&&n--;--p);for(;isalnum(*++p)|*p==95;putchar(*p));}

인덱스가 0 인 인덱스를 취하는 함수를 정의한 다음 문자열을 정의합니다.


나는 isalnum(*++p)|*p==95정의되지 않은 행동 이라고 생각 합니다.
owacoder

@owacoder 그러나 중요한 것은 gcc가 작동하는 실행 파일을 뱉어내는 것입니다. *++p^95?isalnum(*p):11 바이트 더 길지만 모든 컴파일러에서 작동합니다.
orlp

선행 공간이 오타라고 가정합니까? 또한, 여기에 게으른 IDEone 링크.
FryAmTheEggman

isalnum(*++p)||*p==95추가 된 1 바이트에도 작동합니다.
owacoder

@FryAmTheEggman 네, 이제 고쳐졌습니다.
orlp

3

망막, 22

(1) + ¶ (? <-1>.) * \ b | \ W. +

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 . 일반 프로그램은 커서 위치를 단항으로, 줄 바꿈과 문자열을 차례로 사용합니다. 테스트 스위트에는 라인 당 모드로 실행할 추가 코드가 \있으며, 구분 기호로 a를 사용하고 편의상 10 진수를 사용합니다.

밸런싱 그룹을 사용하여 커서 위치를 찾은 다음 단어 경계까지 역 추적합니다. 단어까지 텍스트를 삭제 한 다음 단어 뒤에서 삭제합니다.


2

C, 115 바이트

함수 f()는 문자열 및 색인 (1 색인)을 매개 변수로 필요로하며 결과를 stdout에 인쇄합니다. 커서는 지정된 문자 뒤에 있어야합니다.

f(char*p,int n){char*s=p+n;for(;s>=p&&isalnum(*s)+(*s==95);--s);for(p=s+1;*p&&isalnum(*p)+(*p==95);putchar(*p++));}

2

자바 스크립트 (ES6), 57 바이트

f=(s,n)=>s.slice(0,n).match(/\w*$/)+s.slice(n).match(/\w*/)

단순히 커서 포인트에서 문자열을 슬라이스하면 (0 인덱스 문자 앞, 1 인덱스 문자와 동일하게 작동) 인접한 단어 조각을 추출하고 연결합니다. 커서가 단어의 시작, 끝 또는 근처에있을 때도 합리적인 결과를 반환합니다.


마지막 정규식에서 *가 필요합니까?
Charlie Wynn

@CharlieWynn 네, 그렇지 않으면 두 번째 테스트 케이스는을 반환 de합니다.
Neil

으악, 내가 실행 한 테스트에 운이 없어
Charlie Wynn

2

자바 8, 86 78 바이트

(s,p)->{for(String t:s.split("\\W"))if((p-=t.length()+1)<0)return t;return"";}

테스트 케이스를 사용하지 않은 경우 :

class Indexer {
    public static String f(String s, int p) {
        for(String t : s.split("\\W"))
            if((p -= t.length()+1) < 0)
                return t;
        return "";
    }

    public static void main(String[] args) {
        System.out.println(f("abc def",2));
        System.out.println(f("abc def",5));
        System.out.println(f("abc abc",2));
        System.out.println(f("ab cd ef",4));
        System.out.println(f("ab   cd",6));
        System.out.println(f("ab!cd",1));
    }
}

영숫자가 아닌 문자로 문자열을 분할 한 다음 음수가 될 때까지 지정된 위치에서 각 부분 문자열의 길이에 1을 더한 값을 더합니다. 영숫자가 아닌 반복되는 모든 문자열이 빈 문자열로 표시되므로 빼기 논리가 훨씬 더 쉽습니다.

이 코드는 광범위하게 테스트되지 않았으므로 누군가이 문제를 해결할 수 있는지 확인하고 싶습니다. 또한 이것이 Java 코드라는 점을 고려할 때 어떻게 이것이 가장 긴 대답이 아닙니까? :피


나는 거의 3 년이 알지만 (s,p)->될 수 s->p->태닝의 람다 식 (예를 사용하여 java.util.function.Function<String, java.util.function.Function<String, String>> f). 또한 Java 10으로 전환하면 물론 가능하지는 않지만 이제 가능 String할 수 있습니다 var. 어쨌든 좋은 대답입니다. 이미 어딘가에 이미 업데이트 한 것을 확인했습니다. :)
Kevin Cruijssen



2

파이크, 19 바이트

#Q;cjmli<i+s)lttjR@

여기 사용해보십시오!

용도 Q;무 조작으로 확실히 첫 번째 입력이 제대로 배치되어 있는지 확인합니다

#          )   -  first where
   c           -       input.split()
    ml         -      map(len, ^)
      i<       -     ^[:i]
        i+     -    ^+[i]
          s    -   sum(^)
            lt - len(^)-2

링크를 클릭하면 504 오류가 발생합니다.
Leaky Nun

@LeakyNun 그래, 내가 localhost 링크를 가지고있는 이유를 쓰는 동안 우연히 그것을 죽였다. 그것은 다시 올 것이다
Blue


1
프로그램은 N 번째 단어가 선택된 단어 인 N을 출력하는 것 같습니다. 그러나 전체 단어가 필요합니다
Value Ink

2

파이썬 2, 70 66 바이트

import re
f=lambda x,y,r=re.split:r('\W',x[:y])[-1]+r('\W',x[y:])[0]

원래 문자열에서 커서 색인까지 한 번, 커서 색인에서 시작하는 문자열에서 단어가 아닌 구분 기호로 문자열을 분할합니다. 왼쪽 분할의 마지막 요소와 오른쪽 분할의 첫 번째 요소를 더한 값을 반환합니다. 4 바이트를 절약 한 Leaky Nun에게 감사합니다!


1

클로저, 92 바이트

(fn[x k](let[[u i](map #(re-seq #"\w+"(apply str %))(split-at k x))](str(last u)(nth i 0))))

먼저 위치의 입력 문자열 k을 두 개의 문자열로 나눕니다 . 그런 다음이 문자열에 대해 발생을 찾아 "\w+"목록으로 반환하십시오. 그런 다음 첫 번째 목록의 마지막 요소와 두 번째 목록의 첫 번째 요소를 연결하십시오.

온라인에서 참조하십시오 : https://ideone.com/Dk2FIs


1

자바 스크립트 (ES6), 52 바이트

(s,n)=>RegExp(`^.{0,${n}}(\\W+|^)(\\w+)`).exec(s)[2]

const F = (s,n) => RegExp(`^.{0,${n}}(\\W+|^)(\\w+)`).exec(s)[2]

class Test extends React.Component {
    constructor(props) {
        super(props);
        const input = props.input || '';
        const index = props.index || 0;
        this.state = {
            input,
            index,
            valid: /\w/.test(input),
        };
    }
    onInput = () => {
        const input = this.refs.input.value;
        const index = Math.min(+this.refs.index.value, input.length);
        this.setState({
            input,
            index,
            valid: /\w/.test(input),
        });
    }
    render() {
        const {input, index, valid} = this.state;
        return (
            <tr>
                <td>{ this.props.children }</td>
                <td>
                    <input ref="input" type="text" onInput={this.onInput} value={input} />
                    <input ref="index" type="number" onInput={this.onInput} min="1" max={input.length} value={index} />
                </td> 
                {valid && [
                    <td>{F(input, index)}</td>,
                    <td><pre>{input.slice(0, index)}|{input.slice(index)}</pre></td>,
                ]}
            </tr>
        );
    }
}

class TestList extends React.Component {
    constructor(props) {
        super(props);
        this.tid = 0;
        this.state = {
            tests: (props.tests || []).map(test => Object.assign({
                key: this.tid++
            }, test)),
        };
    }
    addTest = () => {
        this.setState({
            tests: [...this.state.tests, { key: this.tid++ }],
        });
    }
    removeTest = key => {
        this.setState({
            tests: this.state.tests.filter(test => test.key !== key),
        });
    }
    
    render() {
        return (
            <div>
                <table>
                    <thead>
                        <th/>
                        <th>Test</th>
                        <th>Output</th>
                        <th>Diagram</th>
                    </thead>
                    <tbody>
                        {
                            this.state.tests.map(test => (
                                <Test key={test.key} input={test.input} index={test.index}>
                                    <button onClick={() => this.removeTest(test.key)} style={{
                                        verticalAlign: 'middle',
                                    }}>-</button>
                                </Test>
                            ))
                        }
                    </tbody>
                    <tfoot>
                        <td/>
                        <td>
                            <button onClick={this.addTest} style={{
                                width: '100%',
                            }}>Add test case</button>
                        </td>
                    </tfoot>
                </table>
            </div>
        );
    }
}

ReactDOM.render(<TestList tests={[
    { input: 'abc def', index: 2 },
    { input: 'abc def', index: 5 },
    { input: 'abc abc', index: 2 },
    { input: 'ab cd ef', index: 4 },
    { input: 'ab   cd', index: 6 },
    { input: 'ab!cd', index: 1 },
]} />, document.body);
input[type="number"] {
  width: 3em;
}
table {
  border-spacing: 0.5em 0;
  border-collapse: separate;
  margin: 0 -0.5em ;
}
td, input {
    font-family: monospace;
}
th {
  text-align: left;
}
tbody {
  padding: 1em 0;
}
pre {
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


(\\W+|^)하지(\\W|^)
l4m2

1

루아, 71 67 바이트

우후, 루아가 가장 긴 해결책은 아닙니다! 여전히 파이썬 뒤에 1 바이트가 있지만 이것을 어떻게 골라 내는지 모른다. 인덱스는 1부터 시작합니다.

@LeakyNun 덕분에 저에게 string.match4 바이트를 절약했습니다.

g,h=...print(g:sub(1,h):match"[%a_]*$"..g:sub(h+1):match("[%a_]+"))

올드 71

참고 : 설명은 새로운 설명에도 적용되지만 이에 대한 추가 정보가 포함되어 있기 때문에 여전히이 설명을 기반으로합니다. gmatch

g,h=...print(g:sub(1,h):gmatch"[%a_]*$"()..g:sub(h+1):gmatch"[%a_]*"())

설명

첫째, 우리는에 인수를 풀고 gh그들이보다 짧은 때문에arg[x]

g,h=...

그런 다음 커서 앞뒤로 부품을 연결하는 출력을 구성합니다.

문자열의 첫 부분은

g:sub(1,h)

이 단어의 끝에서 단어를 찾고 싶기 때문에 함수를 사용합니다. string.gmatch

:gmatch"[%a_]*$"

이 패턴 일치 0..n는 문자열 끝에서 알파벳 + 밑줄 문자 세트를 곱합니다. gmatch함수의 형태로 일치 목록에서 반복자를 반환합니다 (폐쇄 원리 사용). 단어의 첫 부분을 얻기 위해 한 번 실행합니다.

g:sub(1,h):gmatch"[%a_]*$"()

우리는 같은 방식으로 단어의 두 번째 부분을 얻습니다.

g:sub(h+1):gmatch"[%a_]*"())

유일한 차이점은 문자열을 시작할 때 (을 사용하여 [^%a_]*) 일치 시키도록 지정할 필요가 없다는 것입니다. 반복자가 처음 호출 할 때 반복자가 반환하는 일치이기 때문입니다.


g:sub(h+1):match"^[%a_]*"?
Leaky Nun

@LeakyNun 완전히 match\ o / 의 존재를 잊어 버렸습니다. 많은 바이트를 절약 할 수 있습니다.
Katenkyo

"indexes"에 대해 -1
Leaky Nun


상관없이 "인덱스"에 대해서는 여전히 -1입니다.
Leaky Nun

1

자바 스크립트 (외부 라이브러리 사용) (168 바이트)

(n,w)=> _.From(w).Select((x,i)=>({i:i,x:x})).Split((i,v)=>v.x==" ").Where(a=>a.Min(i=>i.i)<=n-1&&a.Max(i=>i.i)>=n-2).First().Select(i=>i.x).Write("").match(/^\w*^\w*/)[0]

lib에 링크 : https://github.com/mvegh1/Enumerable/blob/master/linq.js

코드 설명 : 라이브러리는 문자열을 받아들이며 char 배열로 구문 분석됩니다. 인덱스와 문자를 저장하는 객체에 매핑됩니다. ""가 나타날 때마다 시퀀스가 ​​하위 시퀀스로 분할됩니다. 하위 시퀀스는 커서 인덱스가 하위 시퀀스의 최소 및 최대 인덱스 내에 포함되어 있는지 확인하여 필터링됩니다. 그런 다음 첫 번째 하위 시퀀스를 가져옵니다. 그런 다음 char 배열로 다시 변환합니다. 그런 다음 모든 문자를 ""로 구분 기호로 연결합니다. 그런 다음 단어 정규식에 대해 유효성을 검사합니다. 그런 다음 첫 경기를합니다.

여기에 이미지 설명을 입력하십시오


"word"라는 단어는 정규식에 의해 정의되며 (?<!\w)\w+(?!\w), 여기서 "또는 밑줄을 포함하여 ASCII의 영숫자"로 \w정의됩니다 [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_].
Leaky Nun

regex101.com에서 ab! cd에 대해 해당 정규 표현식을 실행하면 다음과 같은 결과가 나타납니다. 일치 그룹이 추출되지 않았습니다. 이것은 패턴이 일치하지만 주제 문자열의 어떤 것과 일치하는 (캡처 (그룹))이 없음을 의미합니다. 어쩌면 내가 실수의 어딘가를 만들고 있어요 ...
applejacks01

왜 무엇을 캡처해야합니까?
Leaky Nun

나는 이것이 배울 곳이 아니라는 것을 알고 있지만, ab! cd에 대해 정규 표현식을 실행할 때 아무것도 얻지 못한다고 말하고 있습니다. 그렇다면 왜 'ab'가 올바른 결과일까요?
applejacks011


1

펄 6 , 34 바이트

->\b{&{first *.to>b,m:g/<<\w+>>/}}

온라인으로 사용해보십시오!

처럼 입력을받는 익명의 코드 블록 f(n)(string).

설명:

->\b{                            }   # Anonymous code block that takes a number
     &{                         }    # And returns another code block that
       first       ,m:g/<<\w+>>/     # Finds the first word in the input
             *.to>b                  # Where the start is after the number


1

APL (NARS), 58 자, 116 바이트

{m←⎕A,⎕a,⎕D,'_'⋄↑v⊂⍨m∊⍨v←⍵↓⍨¯1+⍵{⍵≤1:⍵⋄m∊⍨⍵⊃⍺:⍺∇⍵-1⋄⍵+1}⍺}

⍵ {⍵≤1 : ⍵⋄m∊⍨⍵⊃⍺ : ⍺∇⍵-1⋄⍵ + 1} ⍺ 문자열 시작 위치 찾기 ... 사용 방법 및 테스트 방법 :

  f←{m←⎕A,⎕a,⎕D,'_'⋄↑v⊂⍨m∊⍨v←⍵↓⍨¯1+⍵{⍵≤1:⍵⋄m∊⍨⍵⊃⍺:⍺∇⍵-1⋄⍵+1}⍺}
  2 f 'abc def'
abc
  5 f 'abc def'
def
  2 f 'abc abc'
abc
  4 f 'ab cd ef'
cd
  1 f 'ab!cd'
ab
  6 f 'ab   cd'
cd 

0

MATL , 16 15 바이트

'\w+'5B#XXi>)1)

커서는 1 인덱싱되고 문자 뒤 (테스트 사례에서와 같이)입니다.

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

'\w+'    % Push string to be used as regex pattern
5B#XX    % Take input string implicitly. Apply regex. Push matches and ending indices
i>       % Take input number. Compare with obtained ending indices. Gives true for
         % ending indices that exceed the input number
)        % Use as logical index to select the corresponding matches
1)       % Select the first match. Implicitly display

0

PowerShell v3 +, 103101 바이트

param($a,$n)for(;$n[++$a]-match'\w'){}$i=$a--;for(;$n[--$a]-match'\w'-and$a-ge0){}-join$n[++$a..--$i]

구피 솔루션의 종류이지만 다른 방법과는 다른 접근 방식입니다.

입력 $a을 문자열의 0 기반 인덱스로 사용합니다 $n. 그런 다음 단어의 경계를 찾습니다. 우리는 문자열의 끝에 도달하지 못했거나 여전히 단어 문자와 일치하지만 ++$a. 그런 다음 펜스 포스팅으로 인해 설정했습니다 $i=$a--. 다음으로 우리는 뒤로 크롤링 하여 단어가 아닌 문자에 도달 $a할 때까지 감소 0합니다. 그런 다음이 두 가지 구분 (OBOE를 설명하기 위해 증분 / 감소 포함)을 기반으로 입력 문자열을 슬라이스하고 -join함께 결과를 생성합니다.

PS C:\Tools\Scripts\golfing> .\select-the-word-around-the-index.ps1 2 'This!test'
This

PS C:\Tools\Scripts\golfing> .\select-the-word-around-the-index.ps1 5 'This!test'
test

select-the-word-around-the-index.ps1
Leaky Nun

0

PHP, 98 바이트

function f($s,$p){foreach(preg_split('#\W+#',$s,-1,4)as$m)if($m[1]+strlen($m[0])>=$p)return$m[0];}
  • 문자열을 단어가 아닌 문자로 나누고 위치 ( 4== PREG_SPLIT_OFFSET_CAPTURE)를 기억하고 위치에 도달 할 때까지 단어를 반복합니다.
  • PHP 문자열은 0- 인덱싱되고 문자 앞에 커서가 있지만 단어 앞이나 뒤에있을 수 있습니다.

0

파이썬 3, 112140 바이트

from string import*
p='_'+printable[:62]
def f(s,h,r=''):
 while s[h]in p and h>-1:h-=1
 while h+1<len(s)and s[h]in p:h+=1;r+=s[h]
 return r

인덱스가 0입니다.

색인에서 첫 번째 영숫자 문자를 찾은 다음 색인 후 마지막 영숫자 문자로 이동합니다. 더 똑똑한 방법이있을 것입니다.

시도 해봐


@LeakyNun _이 추가 되었지만 왜 오류가 발생하는지 잘 모르겠습니다 f('abc',1).
atlasologist

0

자바 스크립트 (ES 6), 43 42 바이트

s=>n=>s.replace(/\w*/g,(x,y)=>y<n?s=x:0)&&s

자바 스크립트 (ES 3), 65 바이트

function(s,n){s.replace(/\w*/g,function(x,y){y<n?s=x:0});alert(s)}

0

05AB1E , 14 바이트

ð«._DžjмS¡Á2£J

@AndersKaseorg 의 Pyth 답변 포트 .

챌린지 테스트 사례와 같이 1- 인덱싱되었습니다.

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

ð«              # Append a space to the (implicit) input-String
  ._            # Rotate this string the (implicit) input-integer amount of times
                #  towards the left
     D          # Duplicate this string
      žjм       # Remove [a-zA-Z0-9_] from the string
         S¡     # Split the rotated string by each of the remaining characters
           Á    # Rotate the resulting list once towards the right
            2£J # And only leave the first two items, joined together
                # (which is output implicitly)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.