Java에서 유니코드 에이전트 프로그래밍을 사용하는 방법
순차 접근
순차 접근은 자바 언어에서 문자열을 처리하기 위한 기본 작업입니다. 이 접근 방식에서는 입력 문자열의 각 문자에 처음부터 끝까지 또는 때로는 끝에서 처음까지 순차적으로 액세스됩니다. 이 섹션에서는 순차 액세스 방법을 사용하여 문자열에서 32비트 코드 포인트 배열을 생성하고 처리 시간을 추정하는 7가지 기술 예제를 논의합니다.
예제 1-1: 벤치마크 테스트(대리 쌍은 지원되지 않음)
목록 1 서로게이트 쌍을 전혀 고려하지 않고 16비트 문자 유형 값을 32비트 코드 포인트 값에 직접 할당:
Listing 1. 지원되지 않는 프록시 쌍
int[] toCodePointArray(String str) { // Example 1-1 int len = str.length(); // the length of str int[] acp = new int[len]; // an array of code points for (int i = 0, j = 0; i <p> 이 예는 서로게이트 쌍을 지원하지 않지만 후속 순차 액세스 예와 비교할 수 있는 처리 시간 기준을 제공합니다. </p><p><strong>예제 1-2: isSurrogatePair() 사용</strong></p><p>목록 2 isSurrogatePair()를 사용하여 총 대리 쌍 수를 계산합니다. 계산 후에는 값을 저장하기 위해 코드 비트 배열에 충분한 메모리를 할당합니다. 그런 다음 isHighSurrogate() 및 isLowSurrogate()를 사용하여 각 서로게이트 쌍 문자가 상위 또는 하위 서로게이트인지 확인하는 순차 액세스 루프에 들어갑니다. 상위 서로게이트와 하위 서로게이트를 찾으면 toCodePoint()를 사용하여 서로게이트 쌍을 코드 포인트 값으로 변환하고 현재 인덱스 값을 2만큼 증가시킵니다. 그렇지 않으면 char 유형 값을 코드 포인트 값에 직접 할당하고 현재 인덱스 값을 1씩 증가시킵니다. 이 예는 예 1-1보다 처리하는 데 1.38배 더 오래 걸립니다. </p><p><strong>목록 2. 제한된 지원 </strong></p><pre class="brush:php;toolbar:false">int[] toCodePointArray(String str) { // Example 1-2 int len = str.length(); // the length of str int[] acp; // an array of code points int surrogatePairCount = 0; // the count of surrogate pairs for (int i = 1; i <p>목록 2의 소프트웨어 업데이트 접근 방식은 순진합니다. 이는 번거롭고 광범위한 수정이 필요하므로 결과 소프트웨어가 부서지기 쉽고 향후 변경이 어렵습니다. 구체적으로 이러한 문제는 다음과 같습니다. </p><p>◆충분한 메모리를 할당하려면 코드 포인트 수를 계산해야 합니다. </p><p>◆문자열의 특정 인덱스에 대한 올바른 코드 포인트 값을 얻기 어렵습니다. </p><p>◆이동이 어렵습니다. 다음 처리 단계에서 정확하게 현재 인덱스 </p><p> 향상된 알고리즘이 다음 예에 나타납니다. </p><p><strong>예: 기본 지원</strong></p><p>Java 1.5는 예제 1-2의 세 가지 문제를 각각 처리하기 위해 codePointCount(), codePointAt() 및 offsetByCodePoints() 메서드를 제공합니다. Listing 3에서는 이 알고리즘의 가독성을 높이기 위해 다음 방법을 사용합니다. </p><p><strong>Listing 3. 기본 지원 </strong></p><pre class="brush:php;toolbar:false">int[] toCodePointArray(String str) { // Example 1-3 int len = str.length(); // the length of str int[] acp = new int[str.codePointCount(0, len)]; for (int i = 0, j = 0; i <p>그러나 Listing 3은 Listing 1보다 처리하는 데 2.8배 더 오래 걸립니다. </p><p><strong>예제 1-4: codePointBefore() 사용</strong></p><p>offsetByCodePoints()가 두 번째 매개 변수로 음수를 받으면 문자열의 선두에서 절대 오프셋 값을 계산할 수 있습니다. 다음으로, codePointBefore()는 지정된 인덱스 이전의 코드 포인트 값을 반환할 수 있습니다. 이러한 메소드는 목록 4의 끝에서 시작까지 문자열을 반복하는 데 사용됩니다. </p><p><strong>목록 4. codePointBefore()에 대한 기본 지원 사용 </strong></p><pre class="brush:php;toolbar:false">int[] toCodePointArray(String str) { // Example 1-4 int len = str.length(); // the length of str int[] acp = new int[str.codePointCount(0, len)]; int j = acp.length; // an index for acp for (int i = len; i > 0; i = str.offsetByCodePoints(i, -1)) { acp[--j] = str.codePointBefore(i); } return acp; }
이 예제는 예제 1-1 - 예제 1보다 처리하는 데 2.72배 더 오래 걸립니다. -3이 더 빠릅니다. 일반적으로 0이 아닌 값 대신 0을 비교할 때 JVM의 코드 크기가 더 작아져 성능이 향상되는 경우도 있습니다. 그러나 작은 개선으로 인해 가독성이 희생될 만큼 가치가 있는 것은 아닙니다.
예 1-5: charCount() 사용
예 1-3과 1-4는 기본 서로게이트 쌍 지원을 제공합니다. 임시 변수가 필요하지 않으며 강력한 코딩 방법입니다. 처리 시간을 단축하려면 offsetByCodePoints() 대신 charCount()를 사용하는 것이 효과적이지만 목록 5에 표시된 것처럼 코드 포인트 값을 저장하기 위한 임시 변수가 필요합니다.
목록 5. charCount()를 사용한 최적화 에 대한 지원
int[] toCodePointArray(String str) { // Example 1-5 int len = str.length(); // the length of str int[] acp = new int[str.codePointCount(0, len)]; int j = 0; // an index for acp for (int i = 0, cp; i <p>목록 5의 처리 시간은 예제 1-1보다 1.68배로 단축되었습니다. </p><p><strong>예 1-6: char 배열에 액세스</strong></p><p>Listing 6 예 1-5에 표시된 최적화를 사용하면서 char 유형의 배열에 직접 액세스: </p><p><strong>Listing 6. char 배열 사용에 대한 최적화된 지원</strong> </p> <pre class="brush:php;toolbar:false">int[] toCodePointArray(String str) { // Example 1-6 char[] ach = str.toCharArray(); // a char array copied from str int len = ach.length; // the length of ach int[] acp = new int[Character.codePointCount(ach, 0, len)]; int j = 0; // an index for acp for (int i = 0, cp; i <p>Char 배열은 toCharArray()를 사용하여 문자열에서 복사됩니다. 메소드를 통한 간접 액세스보다 어레이에 대한 직접 액세스가 더 빠르기 때문에 성능이 향상됩니다. 처리 시간은 예제 1-1보다 1.51배 더 길다. 그러나 toCharArray()를 호출하면 새 배열을 만들고 데이터를 배열에 복사하는 데 약간의 오버헤드가 필요합니다. String 클래스에서 제공하는 편의 메서드도 사용할 수 없습니다. 그러나 이 알고리즘은 많은 양의 데이터를 처리할 때 유용합니다. </p><p><strong>예제 1-7: 객체 지향 알고리즘 </strong></p><p>이 예의 객체 지향 알고리즘은 목록 7에 표시된 대로 CharBuffer 클래스를 사용합니다. </p><p><strong>목록 7. CharSequence를 사용하는 객체 지향 알고리즘 </strong></p><pre class="brush:php;toolbar:false">int[] toCodePointArray(String str) { // Example 1-7 CharBuffer cBuf = CharBuffer.wrap(str); // Buffer to wrap str IntBuffer iBuf = IntBuffer.allocate( // Buffer to store code points Character.codePointCount(cBuf, 0, cBuf.capacity())); while (cBuf.remaining() > 0) { int cp = Character.codePointAt(cBuf, 0); // the current code point iBuf.put(cp); cBuf.position(cBuf.position() + Character.charCount(cp)); } return iBuf.array(); }
이전과 동일 예제와 달리 Listing 7에서는 순차 액세스를 위해 현재 위치를 유지하는 데 인덱스가 필요하지 않습니다. 대신 CharBuffer는 내부적으로 현재 위치를 추적합니다. Character 클래스는 CharSequence 인터페이스를 통해 CharBuffers를 처리하는 정적 메서드 codePointCount() 및 codePointAt()를 제공합니다. CharBuffer는 항상 현재 위치를 CharSequence의 헤드로 설정합니다. 따라서 codePointAt()가 호출되면 두 번째 매개변수는 항상 0으로 설정됩니다. 예제 1-1보다 처리 시간이 2.15배 더 길다.
处理时间比较
这些顺序访问示例的计时测试使用了一个包含 10,000 个代理对和 10,000 个非代理对的样例字符串。码位数组从这个字符串创建 10,000 次。测试环境包括:
◆OS:Microsoft Windows® XP Professional SP2
◆Java:IBM Java 1.5 SR7
◆CPU:Intel® Core 2 Duo CPU T8300 @ 2.40GHz
◆Memory:2.97GB RAM
表 1 展示了示例 1-1 到 1-7 的绝对和相对处理时间以及关联的 API:
表 1. 顺序访问示例的处理时间和 API
随机访问
随机访问是直接访问一个字符串中的任意位置。当字符串被访问时,索引值基于 16 位 char 类型的单位。但是,如果一个字符串使用 32 位码位,那么它不能使用一个基于 32 位码位的单位的索引访问。必须使用 offsetByCodePoints() 来将码位的索引转换为 char 类型的索引。如果算法设计很糟糕,这会导致很差的性能,因为 offsetByCodePoints() 总是通过使用第二个参数从第一个参数计算字符串的内部。在这个小节中,我将比较三个示例,它们通过使用一个短单位来分割一个长字符串。
示例 2-1:基准测试(不支持代理对)
清单 8 展示如何使用一个宽度单位来分割一个字符串。这个基准测试留作后用,不支持代理对。
清单 8. 不支持代理对
String[] sliceString(String str, int width) { // Example 2-1 // It must be that "str != null && width > 0". List<string> slices = new ArrayList<string>(); int len = str.length(); // (1) the length of str int sliceLimit = len - width; // (2) Do not slice beyond here. int pos = 0; // the current position per char type while (pos <p>sliceLimit 变量对分割位置有所限制,以避免在剩余的字符串不足以分割当前宽度单位时抛出一个 IndexOutOfBoundsException 实例。这种算法在当前位置超出 sliceLimit 时从 while 循环中跳出后再处理最后的分割。</p> <p><strong>示例 2-2:使用一个码位索引</strong></p> <p>清单 9 展示了如何使用一个码位索引来随机访问一个字符串:</p> <p><strong>清单 9. 糟糕的性能</strong></p> <pre class="brush:php;toolbar:false">String[] sliceString(String str, int width) { // Example 2-2 // It must be that "str != null && width > 0". List<string> slices = new ArrayList<string>(); int len = str.codePointCount(0, str.length()); // (1) code point count [Modified] int sliceLimit = len - width; // (2) Do not slice beyond here. int pos = 0; // the current position per code point while (pos <p>清单 9 修改了 清单 8 中的几行。首先,在 Line (1) 中,length() 被 codePointCount() 替代。其次,在 Lines (3)、(4) 和 (6) 中,char 类型的索引通过 offsetByCodePoints() 用码位索引替代。</p> <p>基本的算法流与 示例 2-1 中的看起来几乎一样。但处理时间根据字符串长度与示例 2-1 的比率同比增加,因为 offsetByCodePoints() 总是从字符串头到指定索引计算字符串内部。</p> <p><strong>示例 2-3:减少的处理时间</strong></p> <p>可以使用清单 10 中展示的方法来避免 示例 2-2 的性能问题:</p> <p><strong>清单 10. 改进的性能</strong></p> <pre class="brush:php;toolbar:false">String[] sliceString(String str, int width) { // Example 2-3 // It must be that "str != null && width > 0". List<string> slices = new ArrayList<string>(); int len = str.length(); // (1) the length of str int sliceLimit // (2) Do not slice beyond here. [Modified] = (len >= width * 2 || str.codePointCount(0, len) > width) ? str.offsetByCodePoints(len, -width) : 0; int pos = 0; // the current position per char type while (pos <p>首先,在 Line (2) 中,(清单 9 中的)表达式 len-width 被 offsetByCodePoints(len,-width) 替代。但是,当 width 的值大于码位的数量时,这会抛出一个 IndexOutOfBoundsException 实例。必须考虑边界条件以避免异常,使用一个带有 try/catch 异常处理程序的子句将是另一个解决方案。如果表达式 len>width*2 为 true,则可以安全地调用 offsetByCodePoints(),因为即使所有码位都被转换为代理对,码位的数量仍会超过 width 的值。或者,如果 codePointCount(0,len)>width 为 true,也可以安全地调用 offsetByCodePoints()。如果是其他情况,sliceLimit 必须设置为 0。</p> <p>在 Line (4) 中,清单 9 中的表达式 pos + width 必须在 while 循环中使用 offsetByCodePoints(pos,width) 替换。需要计算的量位于 width 的值中,因为第一个参数指定当 width 的值。接下来,在 Line (5) 中,表达式 pos+=width 必须使用表达式 pos=end 替换。这避免两次调用 offsetByCodePoints() 来计算相同的索引。源代码可以被进一步修改以最小化处理时间。</p> <h3 id="处理时间比较">处理时间比较</h3> <p>图 1 和图 2 展示了示例 2-1、2-2 和 2-3 的处理时间。样例字符串包含相同数量的代理对和非代理对。当字符串的长度和 width 的值被更改时,样例字符串被切割 10,000 次。</p> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/164/168337700040575.png" class="lazy" alt="Java에서 유니코드 에이전트 프로그래밍을 사용하는 방법"></p> <p><strong>图 1. 一个分段的常量宽度</strong></p> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/164/168337700041405.png" class="lazy" alt="Java에서 유니코드 에이전트 프로그래밍을 사용하는 방법"></p> <p><strong>图 2. 分段的常量计数</strong></p> <p>示例 2-1 和 2-3 按照长度比例增加了它们的处理时间,但 示例 2-2 按照长度的平方比例增加了处理时间。当字符串长度和 width 的值增加而分段的数量固定时,示例 2-1 拥有一个常量处理时间,而示例 2-2 和 2-3 以 width 的值为比例增加了它们的处理时间。</p> <h3 id="信息-API">信息 API</h3> <p>大多数处理代理的信息 API 拥有两种名称相同的方法。一种接收 16 位 char 类型参数,另一种接收 32 为码位参数。表 2 展示了每个 API 的返回值。第三列针对 U+53F1,第 4 列针对 U+20B9F,最后一列针对 U+D842(即高代理),而 U+20B9F 被转换为 U+D842 加上 U+DF9F 的代理对。如果程序不能处理代理对,则值 U+D842 而不是 U+20B9F 将导致意想不到的结果(在表 2 中以粗斜体表示)。</p> <p><strong>表 2. 用于代理的信息 API</strong></p> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/164/168337700086359.gif" class="lazy" alt="Java에서 유니코드 에이전트 프로그래밍을 사용하는 방법"></p> <h3 id="其他-API">其他 API</h3> <p>本小节介绍前面的小节中没有讨论的代理对相关 API。表 3 展示所有这些剩余的 API。所有代理对 API 都包含在表 1、2 和 3 中。</p> <p><strong>表 3. 其他代理 API</strong></p> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/164/168337700025390.gif" class="lazy" alt="Java에서 유니코드 에이전트 프로그래밍을 사용하는 방법"></p> <p>清单 11 展示了从一个码位创建一个字符串的 5 种方法。用于测试的码位是 U+53F1 和 U+20B9F,它们在一个字符串中重复了 100 亿次。清单 11 中的注释部分显示了处理时间:</p> <p><strong>清单 11. 从一个码位创建一个字符串的 5 种方法</strong></p> <pre class="brush:php;toolbar:false">int cp = 0x20b9f; // CJK Ideograph Extension B String str1 = new String(new int[]{cp}, 0, 1); // processing time: 206ms String str2 = new String(Character.toChars(cp)); // 187ms String str3 = String.valueOf(Character.toChars(cp)); // 195ms String str4 = new StringBuilder().appendCodePoint(cp).toString(); // 269ms String str5 = String.format("%c", cp); // 3781ms
str1、str2、str3 和 str4 的处理时间没有明显不同。相反,创建 str5 花费的时间要长得多,因为它使用 String.format(),该方法支持基于本地和格式化信息的灵活输出。str5 方法应该只用于程序的末尾来输出文本。
위 내용은 Java에서 유니코드 에이전트 프로그래밍을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

phphassignificallyimpactedwebdevelopmentandextendsbeyondit

PHP가 많은 웹 사이트에서 선호되는 기술 스택 인 이유에는 사용 편의성, 강력한 커뮤니티 지원 및 광범위한 사용이 포함됩니다. 1) 배우고 사용하기 쉽고 초보자에게 적합합니다. 2) 거대한 개발자 커뮤니티와 풍부한 자원이 있습니다. 3) WordPress, Drupal 및 기타 플랫폼에서 널리 사용됩니다. 4) 웹 서버와 밀접하게 통합하여 개발 배포를 단순화합니다.

PHP는 웹 개발 및 컨텐츠 관리 시스템에 적합하며 Python은 데이터 과학, 기계 학습 및 자동화 스크립트에 적합합니다. 1.PHP는 빠르고 확장 가능한 웹 사이트 및 응용 프로그램을 구축하는 데 잘 작동하며 WordPress와 같은 CMS에서 일반적으로 사용됩니다. 2. Python은 Numpy 및 Tensorflow와 같은 풍부한 라이브러리를 통해 데이터 과학 및 기계 학습 분야에서 뛰어난 공연을했습니다.
