Back home

ARTES #002

ARTES #002

ARTS é uma atividade iniciada por 由左耳朵耗子--陈皓: Faça pelo menos uma pergunta sobre o algoritmo leetcode toda semana, leia e comente pelo menos um artigo técnico em inglês, aprenda pelo menos uma habilidade técnica e compartilhe um artigo com opiniões e pensamentos. (Ou seja, Algoritmo, Revisão, Dica e Compartilhamento são chamados de ARTS) e persistem por pelo menos um ano.

ARTES 002

Este é o segundo artigo e está relativamente mal escrito. Espero que fique cada vez melhor no futuro.

Pergunta sobre algoritmo de algoritmo

Pergunta do algoritmo leetcode 242 Anagrama válido (verifique se é um anagrama)

Given two strings s and t , write a function to determine if t is an anagram of s.
Example 1:
Input: s = "anagram", t = "nagaram"
Output: true
Example 2:
Input: s = "rat", t = "car"
Output: false
Note:
You may assume the string contains only lowercase alphabets.

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
说明:
你可以假设字符串只包含小写字母。

A ideia inicial é ordenar primeiro e depois comparar, ou seja, ordenar primeiro as duas strings e depois comparar se são iguais. Este método de verificação é o mais eficiente. Você pode usar classificação por bolha, classificação por seleção, classificação por inserção, etc. Embora a complexidade desses três algoritmos de classificação seja O(n<sup>2</sup>), o teste descobriu que quando a quantidade de dados é grande, a classificação por inserção é muito mais rápida que os outros dois, o que não está na mesma ordem de magnitude. A implementação da classificação por inserção é a seguinte:

char* insertionSort(char* str) {
    for (int j = 1; j < strlen(str); j++) {
        char *insertionChar = str + j;
        char iChar = *insertionChar;
        char * compareChar = insertionChar;
        
        for (int i = j-1; i >=0; i--) {
            if (iChar < *(str + i)) {
                compareChar = str + i;
                *(compareChar +1) = *compareChar;
            }
            else{
                break;
            }
        }
        *compareChar = iChar;
    }
    return str;
}

bool isAnagram(char* s, char* t) {
    if (strlen(s) != strlen(t)){
        return false;
    }
    char *s1 = insertionSort(s);
    char *s2 = insertionSort(t);
    
    if (strcmp(s1,s2)) {
        return false;
    }
    else{
        return true;
    }
}

Mas não pode passar no leetcode. O comprimento da sequência de dados de teste no leetcode é 100 KB. Eu medi localmente e demorou quase 20 segundos usando a classificação por inserção. Mas se eu usar a classificação por bolha e seleção, demorei mais de uma hora para terminar.

Se esse método não funcionar, você pode tentar outra ideia. Você pode contar se os tipos de caracteres e números contidos na string são iguais. Por exemplo, a string s contém 10 letras a, 5 letras b e 8 letras k. Se o mesmo for verdade para a string t, então s é um anagrama de t. Implementado da seguinte forma

bool isAnagram(char* s, char* t) {
    if (strlen(s) != strlen(t)){
        return false;
    }

    int af[26]= {0};
    while (*s) {
        af[*s++ - 'a']+=1;
    }
    while (*t) {
        af[*t++  - 'a']-=1;
    }
    
    for (int i = 0; i<26; i++) {
        if (af[i] != 0) {
            return false;
        }
    }
    return true;
}

Ao implementar isso, apenas um array é usado em vez de dois arrays para contar o número de caracteres que aparecem em duas strings, respectivamente. Isso pode evitar situações fora dos limites devido a muitas ocorrências de um determinado personagem.

Revisão

O seguinte artigo vem de: https://littlebitesofcocoa.com/251-face-aware-image-views-with-aspectfillfaceaware;. Ele fala sobre o uso de AspectFillfaceaware para perceber que ao definir uma imagem para imageView, se a imagem contiver um rosto, o rosto poderá ser exibido automaticamente no centro.

Visualizações de imagens com reconhecimento de rosto com AspectFillFaceAware (use AspectFillFaceAware para permitir que o imageView reconheça rostos)

Ao usar UIImageViews, às vezes os modos de conteúdo integrados podem prejudicar nosso estilo.

Ao usar UIImageViews, às vezes o modo de conteúdo integrado destrói nosso estilo e não consegue atender às nossas necessidades.

Muitas vezes, exibimos fotos de pessoas. Nesses casos, seria ótimo se a visualização da imagem pudesse, de alguma forma, ser informada para cortar de forma inteligente a foto ao redor do rosto da pessoa.

Muitas vezes mostramos fotos de pessoas. Nesses casos, seria ótimo se a visualização da imagem pudesse, de alguma forma, cortar de forma inteligente a foto ao redor do rosto da pessoa.

Hoje veremos uma biblioteca do Beau Nouvelle chamada AspectFillFaceAware. É super simples, vamos dar uma olhada.

Hoje vamos dar uma olhada em uma biblioteca de classes da Beau Nouvelle chamada AspectFillFaceAware. É muito simples, vamos dar uma olhada.

AspectFillFaceAware é essencialmente apenas uma extensão do UIImageView. Ele fornece duas maneiras de configurar uma visualização de imagem para “reconhecer o rosto”.

AspectFillFaceAware é essencialmente apenas uma extensão do UIImageView. Ele fornece dois métodos de configuração da visualização da imagem para “reconhecimento facial”.

A primeira está no Interface Builder, podemos habilitar o recurso ativando-o no Inspetor. (Não está vendo a opção? Execute seu projeto uma vez, então ele deverá aparecer).

A primeira maneira é no Interface Builder, podemos habilitar o recurso percorrendo Recursos no Inspetor. (Não vê a opção? Execute seu projeto uma vez e ele deverá aparecer).

<img src=“/img/15334638167496.jpg” largura=“50%” altura=“50%” /> Veja como fica:

Também podemos ativar a funcionalidade no código definindo a imagem da visualização da imagem usando esta nova função:

Também podemos usar esse novo recurso por meio de código:

imageView.set (imagem: avatar, focusOnFaces: verdadeiro) Podemos até mesmo lançar um raio de canto rápido na camada de visualização da imagem para testar a funcionalidade “reconhecer o rosto” em uma visualização circular. (ou seja, avatares de usuários):

Podemos até lançar um raio de canto rápido na camada de visualização da imagem para testar o recurso de “reconhecimento facial” na visualização circular. (ou seja, avatar do usuário):

deixe raio = imageView.bounds.size.width / 2.0 imageView.layer.cornerRadius = raio

Nos bastidores, a biblioteca está usando um CIDetector de baixa precisão com um tipo de CIDetectorTypeFace para lidar com a detecção de rosto real. Quer mergulhar mais fundo aqui? Abordamos os CIDetectors em [Bite # 87.] (https://littlebitesofcocoa.com/87)

Nos bastidores, a biblioteca está usando um CIDetector de baixa precisão com o tipo CIDetectorTypeFace para lidar com a detecção de rosto real. Quer se aprofundar? Introduzimos a abordagem CIDetectors em Bite #87.

Dica

Apresente o método de uso de Proxifier e shadowsocks para obter acesso proxy secundário à Internet. Algumas empresas precisam passar por um proxy para acessar a Internet. Neste caso, não podemos usar shadowocks para acessar a Internet através de um proxy. Por exemplo, a empresa em que estou atualmente usa um proxy para acessar a Internet. Caso queira acessar a rede externa, deverá fazer proxy no servidor da empresa para acessar a Internet. Nesse caso, usar shadowocks diretamente não funcionará. É possível encontrar uma maneira de permitir que os shadowocks também usem um proxy? Então encontrei o software Proxifier. Proxifier, a função desta ferramenta é assumir todas as solicitações emitidas por todos os aplicativos em execução, e então você pode controlar se um aplicativo usa um proxy, para que os aplicativos que não suportam proxy também possam usar um proxy. Originalmente, o cliente SS (shadowsocks) acessa diretamente o servidor proxy SS. Através do Proxifier, o cliente ss pode ser controlado para ir primeiro ao proxy da empresa e depois ao servidor proxy ss. O processo geral é o seguinte

  • O processo de configuração é o seguinte: Abra o Proxifier, selecione a guia Proxies para definir o proxy HTTP da empresa e o proxy Socks5 local:

A porta 127.0.0.1 pode ser aberta para visualizar a configuração avançada do ShadowSocks. Ao iniciar o cliente ShadowSocks, você descobrirá que o Proxifier captura automaticamente o aplicativo chamado ss-local, que é o cliente SS aberto pelo ShadowSocks, e define suas regras de proxy para o proxy da empresa criado anteriormente: Então deixe Localhost e Default ir para ss-local (os dois últimos itens da imagem).

Você pode ver que as três primeiras configurações são diretas. Alguns sites ou aplicativos que não requerem proxy podem ser configurados desta forma. Se você descobrir que alguns aplicativos apresentam problemas após ativar o Proxifier, provavelmente isso é causado pelo proxy. Por exemplo, depois de iniciar o Proxifier, descobri que ele travou quando usei o Xcode para executar o programa C. Mais tarde, descobri que quando o Xcode executava o programa C, ele iniciaria automaticamente um serviço local de debugserver. Como defini o proxy padrão, o serviço não conseguiu se comunicar normalmente. Mudei o debugserver para Direct e ele pode funcionar normalmente. Você pode ver que o Proxifier pode especificar diretamente se um nome de aplicativo usa um proxy ou se um determinado IP usa um proxy. Na verdade, é muito conveniente de usar.

Artigo de referência: http://www.devtalking.com/articles/shadowsocks-guide/ http://blackwolfsec.cc/2016/09/19/Proxifier_Shadowshocks/ https://github.com/cyfdecyf/cow/blob/master/doc/sample-config/rc https://www.latoooo.com/xia_zhe_teng/179.htm http://haoweiguang.me/2017/05/08/Mac下shadowsocks全自动地代理翻墙/ https://blog.e9china.net/tufan/macshanganzhuangcowproxyfanqiangjiaocheng.html

Compartilhar

Recentemente mudei de empresa, uma empresa com sérias horas extras. Quando cheguei aqui, sempre tive vontade de ir embora, mas depois de pensar nisso decidi não ir embora. Uma empresa que pode ser tão grande (ouvi dizer que tem quase 20 mil pessoas em P&D) deve ter algo que valha a pena aprender, então resolvi me acalmar e estudar. Quanto às horas extras, você pode aprender e se aprimorar enquanto faz horas extras. Habilidade, a razão pela qual vim para esta empresa não é porque meu nível técnico não seja bom o suficiente, então tenho que me aprimorar o mais rápido possível. Não sei onde vi uma frase: “Você deve aguentar ou sair daqui”.

Na verdade, muitas coisas são assim. Quando a sua capacidade não é digna da sua ambição, o que você precisa fazer é melhorar a sua capacidade em vez de reclamar do meio ambiente.