문자열에서 일반적인 단어 찾기안녕,
저는 일반적인 단어와 카운트를 출력하는 다음 jsl 코드가 있습니다. 하지만 올바르게 카운트하지 않는 것 같습니다.
내가 얻은 출력은 다음과 같습니다.
일반 단어 = ["c1" => 3, "cate" => 3];
그것은해야합니다
일반 단어 = ["c1" => 3, "cate" =>3, "shotp" => 3];
뭔가 제안이 있나요?
input = "CATE_N_C1_Shotp,CATE_P_C1_Shotp,CATE_P_C1_Shotp";// input string<BR />
// Define boundary characters as _ and ,
boundaryChars = "_,";
// Define the pattern for boundary and word
boundaryPat = Pat Any( boundaryChars ) | Pat Pos( 0 );
wordPat = Pat Break( boundaryChars ) | Pat Rem();
patMatchWord = boundaryPat + Pat Pos()>>position + wordPat>>word + boundaryPat;
// Associative array to count word frequency
wordsToCount = [=>];
// Match pattern in the input
rc = Pat Match( input, patMatchWord
+ Pat Test(
word = Lowercase( word ); // Convert word to lowercase for uniformity
If( Contains( wordsToCount, word ),
wordsToCount[word] = wordsToCount[word] + 1,
wordsToCount[word] = 1
);
)
+ Pat R Pos( 0 ) // The pattern must reach the end
);
// Identify common words (those that appear in all elements)
elements = Words( input, "," );
totalElements = N Items( elements );
commonWords = [=>];
For Each( {{word, count}}, wordsToCount,
If( count == totalElements,
commonWords[word] = count
);
);
// Display the common words and their counts
Show( commonWords );<BR /><BR />// commonWords = ["c1" => 2, "cate" => 2];감사해요
자동화 및 스크립팅Re: 문자열에서 일반적인 단어 찾기좋아요! 몇 가지 변경 사항이 있는데, 아래에 설명해 드리겠습니다.
input = "CATE_N_C1_Shotp,CATE_P_C1_Shotp,CATE_P_C1_Shotp";// input string
// Define boundary characters as _ and ,
boundaryChars = "_,";
// Associative array to count word frequency
wordsToCount = [=> ];
// Match pattern in the input
rc = Pat Match(
Lowercase( input ) || boundaryChars, // pre-normalize and add sentinel at end
Pat Pos( 0 )
+ Pat Repeat(
Pat Break( boundaryChars ) >> word + Pat Span( boundaryChars )
+ Pat Test(
If( Contains( wordsToCount, word ),
wordsToCount[word] = wordsToCount[word] + 1,
wordsToCount[word] = 1
);
1; // explicitly, result of pattest is 'true'
)
)
+ Pat R Pos( 0 ) // The pattern must reach the end
);
// Identify common words (those that appear in all elements)
elements = Words( input, "," );
totalElements = N Items( elements );
commonWords = [=> ];
For Each( {{word, count}}, wordsToCount, If( count == totalElements, commonWords[word] = count ) );
// Display the common words and their counts
Show( commonWords );// commonWords = ["c1" => 3, "cate" => 3, "shotp" => 3];
;
주요 변경 사항은 PatRepeat를 사용하여 한 번에 토큰(단어) 하나씩 입력을 살펴보고 끝에 센티넬 구분 기호를 추가하는 것입니다. 원래 코드는 한 단어만 일치시키려고 시도한 다음 해당 단어가 문자열 끝에 없음을 발견하고 일치 시작 부분을 한 문자 앞으로 이동한 다음 다시 일치시키려고 시도하여 문자열을 살펴봅니다. 마지막 구분 기호가 없기 때문에 마지막 "shotp"가 누락됩니다. pattest의 작업은 센티넬을 추가하는 동시에 사전 소문자로 변경하여 간소화됩니다.
누군가가 words() 함수를 사용하여 센티넬이 필요하지 않은 해결책을 제안할 것이라고 확신합니다.
편집: 어떻게 된 일인지 과거의 이 파수꾼을 놓쳤어요.
Re: 문자열에서 일반적인 단어 찾기JMP 테이블을 활용할 수도 있습니다
Names Default To Here(1);
input = "CATE_N_C1_Shotp,CATE_P_C1_Shotp,CATE_P_C1_Shotp";
input = lowercase(input);
elements = Words(input, ",");
dt = New Table("Data",
New Column("Word", Character, Nominal),
New Column("Elementnr", Numeric, Nominal),
private
);
For Each({element, idx}, elements,
l = Words(element, "_");
nr = Repeat(idx, N Items(l));
r = N Rows(dt);
dt << Add Rows(N Items(l));
dt[r+1::r+N Items(l), 1] = l;
dt[r+1::r+N Items(l), 2] = nr;
);
dt_summary = dt << Summary(
Group(:Word),
N,
Subgroup(:Elementnr),
Freq("None"),
Weight("None"),
Link to original data table(0),
private
);
sums = V Sum((dt_summary[0, 3::N Cols(dt_summary)] > 0)`);
valid_idx = Loc(sums >= N ITems(elements));
words = Associative Array(dt_summary[valid_idx, 1], dt_summary[valid_idx, 2]);
Close(dt, no save);
Close(dt_summary, no save);
show(words);
필요한 경우 수행할 수 있는 몇 가지 작은 최적화도 있습니다.
Re: 문자열에서 일반적인 단어 찾기@Craige_Hales 또 다른 질문이 있습니다. 단어의 순서를 유지하는 것이 가능할까요?
일반 단어 = ["c1" => 3, "cate" => 3, "shotp" => 3];
되어야 합니다
케이티_엔_씨1_샷
일반 단어 = ["cate" => 3, "c1" => 3, "shotp" => 3];
Re: 문자열에서 일반적인 단어 찾기@jthi 단어 순서를 유지하는 게 가능할까요?
다음과 같아야 합니다: words = ["cate" => 3, "c1" => 3, "shotp" => 3];
Re: 문자열에서 일반적인 단어 찾기아마도.
input = "CATE_N_C1_Shotp,CATE_P_C1_Shotp,CATE_P_C1_Shotp";// input string
// Define boundary characters as _ and ,
boundaryChars = "_,";
position = 0;
wordToPosition = [=> ];
// Associative array to count word frequency
wordsToCount = [=> ];
// Match pattern in the input
rc = Pat Match(
Lowercase( input ) || boundaryChars, // pre-normalize and add sentinel at end
Pat Pos( 0 )
+ Pat Repeat(
Pat Break( boundaryChars ) >> word + Pat Span( boundaryChars ) >> sep
+ Pat Test(
position += 1;
If( Contains( wordsToCount, word ),
wordsToCount[word] = wordsToCount[word] + 1,
wordsToCount[word] = 1
);
If( Contains( wordToPosition, word ) & wordToPosition[word] != position,
throw("word ordering not consistent")
);
wordToPosition[word] = position;
if(sep==",", position = 0);
1; // explicitly, result of pattest is 'true'
)
)
+ Pat R Pos( 0 ) // The pattern must reach the end
);
// Identify common words (those that appear in all elements)
elements = Words( input, "," );
totalElements = N Items( elements );
commonWords = [=> ];
For Each( {{word, count}}, wordsToCount, If( count == totalElements, commonWords[word] = count ) );
// Display the common words and their counts
Show( commonWords );// commonWords = ["c1" => 3, "cate" => 3, "shotp" => 3];
Show( wordToPosition );// wordToPosition = ["c1" => 3, "cate" => 1, "n" => 2, "p" => 2, "shotp" => 4];
keys = wordToPosition << getkeys;//{"c1", "cate", "n", "p", "shotp"}
vals = wordToPosition << getvalues;// {3, 1, 2, 2, 4}
sort = Rank( vals );// [2, 3, 4, 1, 5]
keys = keys[sort];// {"cate", "n", "p", "c1", "shotp"}
vals = vals[sort];// {1, 2, 2, 3, 4}
For Each( {k}, keys, If( Contains( commonWords, k ), Show( k, commonWords[k] ) ) );
/*
k = "cate";
commonWords[k] = 3;
k = "c1";
commonWords[k] = 3;
k = "shotp";
commonWords[k] = 3;
*/
throw()는 잠재적인 문제 하나를 경고할 수 있습니다.
Re: 문자열에서 일반적인 단어 찾기가능합니다. 데이터의 예가 하나뿐인데 무엇을 해야 할지 알아내려고 하는 것은 약간 성가신 일입니다. 예를 들어, 같은 단어가 같은 요소에 여러 번 나타날 수 있을까요? 그리고 요소 내에서 순서가 바뀔 수 있을까요?
Re: 문자열에서 일반적인 단어 찾기물론 연관 배열이 필요한 경우 JMP에서 하는 것과 다른 방식으로 정렬할 수는 없지만 순위를 이용하면 얻은 값을 정렬할 수 있습니다.
"jmp table" 솔루션을 유지하려고 노력했습니다(몇 가지 가정을 했습니다)
Names Default To Here(1);
input = "CATE_N_C1_Shotp,CATE_P_C1_Shotp,CATE_P_C1_Shotp";
input = lowercase(input);
elements = Words(input, ",");
dt = New Table("Data",
New Column("Word", Character, Nominal),
New Column("Elementnr", Numeric, Nominal)
);
For Each({element, idx}, elements,
l = Words(element, "_");
nr = Repeat(idx, N Items(l));
r = N Rows(dt);
dt << Add Rows(N Items(l));
dt[r+1::r+N Items(l), 1] = l;
dt[r+1::r+N Items(l), 2] = nr;
);
new_col1 = dt << New Column("C", Numeric, Continuous, Formula(
Col Number(:Elementnr, :Word)
));
new_col2 = dt << New Column("R", Numeric, Continuous, Formula(
Col Min(Col Cumulative Sum(1, :Elementnr), :Word)
));
dt << run formulas;
new_col1 << delete formula;
new_col2 << delete formula;
Summarize(dt, elem = by(:Elementnr));
element_count = N Items(elem);
dt << Delete Rows(dt << get rows where(:C != element_count));
dt << Select Duplicate Rows(Match(:Word)) << Delete Rows << Clear Select;
aa = Associative Array(:Word, :C); // results in AA
r = Rank(:Word << get values); // use Rank to return in original order
Close(dt, No save);
keys = (aa << get keys)[r];
// Values does not need sorting as they always have same values
values = aa << get values;
Write();
show(aa, r, keys, values);